From 70fe51486a39fac8b1d5f52421165815f98ed49a Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Mon, 1 Jun 2026 12:49:32 +0530 Subject: [PATCH 01/12] fix: admin org remove last member --- .../organizations/details/members/columns.tsx | 27 ++++++++++++++----- .../organizations/details/members/index.tsx | 3 +++ .../details/members/remove-member.tsx | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/web/sdk/admin/views/organizations/details/members/columns.tsx b/web/sdk/admin/views/organizations/details/members/columns.tsx index 64da56500..fbcc0130f 100644 --- a/web/sdk/admin/views/organizations/details/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/members/columns.tsx @@ -5,6 +5,7 @@ import { Flex, Text, Menu, + IconButton, } from "@raystack/apsara-v1"; import type { SearchOrganizationUsersResponse_OrganizationUser, @@ -26,6 +27,7 @@ const MemberStates = { interface getColumnsOptions { roles: Role[]; + memberCount: number; handleAssignRoleAction: ( user: SearchOrganizationUsersResponse_OrganizationUser, ) => void; @@ -36,6 +38,7 @@ interface getColumnsOptions { export const getColumns = ({ roles = [], + memberCount, handleAssignRoleAction, handleRemoveMemberAction, }: getColumnsOptions): DataTableColumnDef< @@ -136,9 +139,17 @@ export const getColumns = ({ cell: styles["table-action-column"], }, cell: ({ row }) => { + // The last remaining member of an organization cannot be removed. + const canRemoveMember = memberCount > 1; return ( - } /> + + + + } + /> handleAssignRoleAction(row.original)} @@ -146,12 +157,14 @@ export const getColumns = ({ > Assign role... - handleRemoveMemberAction(row.original)} - data-test-id="admin-remove-member-action" - > - Remove... - + {canRemoveMember && ( + handleRemoveMemberAction(row.original)} + data-test-id="admin-remove-member-action" + > + Remove... + + )} ); diff --git a/web/sdk/admin/views/organizations/details/members/index.tsx b/web/sdk/admin/views/organizations/details/members/index.tsx index 995a712af..7de93a847 100644 --- a/web/sdk/admin/views/organizations/details/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/members/index.tsx @@ -124,6 +124,8 @@ export function OrganizationMembersView() { ); const data = infiniteData?.pages?.flatMap(page => page.orgUsers) || []; + const memberCount = + infiniteData?.pages?.[0]?.pagination?.totalCount ?? data.length; const loading = (isLoading || isFetchingNextPage) && !isError; const onTableQueryChange = (newQuery: DataTableQuery) => { @@ -166,6 +168,7 @@ export function OrganizationMembersView() { const columns = getColumns({ roles, + memberCount, handleAssignRoleAction: openAssignRoleDialog, handleRemoveMemberAction: openRemoveMemberDialog, }); diff --git a/web/sdk/admin/views/organizations/details/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/members/remove-member.tsx index 28f02f866..1f333e4e9 100644 --- a/web/sdk/admin/views/organizations/details/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/members/remove-member.tsx @@ -44,7 +44,7 @@ export const RemoveMember = ({ } catch (error) { const message = error instanceof ConnectError - ? error.message + ? error.rawMessage || error.message : "Unknown error"; toastManager.add({ title: `Failed to remove ${t.member({ case: "lower" })}: ${message}`, type: "error" }); console.error(error); From a6252ca091e55b2a33ad5f5487537530e07142bb Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Mon, 1 Jun 2026 13:01:16 +0530 Subject: [PATCH 02/12] fix: error messages --- web/sdk/admin/components/AssignRole.tsx | 2 +- .../admin/views/organizations/details/members/remove-member.tsx | 2 +- .../organizations/details/projects/members/assign-role.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/sdk/admin/components/AssignRole.tsx b/web/sdk/admin/components/AssignRole.tsx index 5e91f6ecf..2ad4566e5 100644 --- a/web/sdk/admin/components/AssignRole.tsx +++ b/web/sdk/admin/components/AssignRole.tsx @@ -84,7 +84,7 @@ export const AssignRole = ({ } catch (error) { toastManager.add({ title: "Failed to assign role", - description: error instanceof ConnectError ? error.rawMessage : undefined, + description: error instanceof ConnectError ? error.message : undefined, type: "error", }); console.error(error); diff --git a/web/sdk/admin/views/organizations/details/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/members/remove-member.tsx index 1f333e4e9..28f02f866 100644 --- a/web/sdk/admin/views/organizations/details/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/members/remove-member.tsx @@ -44,7 +44,7 @@ export const RemoveMember = ({ } catch (error) { const message = error instanceof ConnectError - ? error.rawMessage || error.message + ? error.message : "Unknown error"; toastManager.add({ title: `Failed to remove ${t.member({ case: "lower" })}: ${message}`, type: "error" }); console.error(error); diff --git a/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx b/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx index 96ec7121f..f2e516388 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx @@ -87,7 +87,7 @@ export const AssignRole = ({ } catch (error) { toastManager.add({ title: "Failed to assign role", - description: error instanceof ConnectError ? error.rawMessage : undefined, + description: error instanceof ConnectError ? error.message : undefined, type: "error", }); console.error(error); From 0ab1e4a74ddebea07a4db27d4838ed985cce13a3 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Mon, 1 Jun 2026 15:25:29 +0530 Subject: [PATCH 03/12] fix: data table number check --- web/apps/admin/src/utils/transform-query.ts | 60 +++++---- .../details/invoices/columns.tsx | 117 +++++++++--------- .../organizations/details/invoices/index.tsx | 3 +- web/sdk/react/utils/transform-query.ts | 64 +++++----- web/sdk/utils/transform-query.ts | 66 +++++----- 5 files changed, 165 insertions(+), 145 deletions(-) diff --git a/web/apps/admin/src/utils/transform-query.ts b/web/apps/admin/src/utils/transform-query.ts index bb0d57fdd..e701e9c62 100644 --- a/web/apps/admin/src/utils/transform-query.ts +++ b/web/apps/admin/src/utils/transform-query.ts @@ -1,10 +1,14 @@ -import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; -import type { RQLRequest, RQLFilter, RQLSort } from "@raystack/proton/frontier"; -import { RQLRequestSchema, RQLFilterSchema, RQLSortSchema } from "@raystack/proton/frontier"; -import { create } from "@bufbuild/protobuf"; +import type { DataTableQuery, DataTableSort } from '@raystack/apsara'; +import type { RQLRequest, RQLFilter, RQLSort } from '@raystack/proton/frontier'; +import { + RQLRequestSchema, + RQLFilterSchema, + RQLSortSchema +} from '@raystack/proton/frontier'; +import { create } from '@bufbuild/protobuf'; // Extract DataTableFilter type from DataTableQuery since it's not exported -type DataTableFilter = NonNullable[number]; +type DataTableFilter = NonNullable[number]; export interface TransformOptions { /** @@ -19,16 +23,16 @@ export interface TransformOptions { /** * Converts a filter value to the appropriate RQLFilter value format */ -function convertFilterValue(value: unknown): RQLFilter["value"] { +function convertFilterValue(value: unknown): RQLFilter['value'] { switch (typeof value) { - case "boolean": - return { case: "boolValue", value }; - case "number": - return { case: "numberValue", value }; - case "string": - return { case: "stringValue", value }; + case 'boolean': + return { case: 'boolValue', value }; + case 'number': + return { case: 'numberValue', value }; + case 'string': + return { case: 'stringValue', value }; default: - return { case: "stringValue", value: value == null ? "" : String(value) }; + return { case: 'stringValue', value: value == null ? '' : String(value) }; } } @@ -37,17 +41,17 @@ function convertFilterValue(value: unknown): RQLFilter["value"] { */ function transformFilter( filter: DataTableFilter, - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLFilter { // Priority: typed values > generic value field - let value: RQLFilter["value"]; + let value: RQLFilter['value']; if (filter.boolValue !== undefined) { - value = { case: "boolValue", value: filter.boolValue }; + value = { case: 'boolValue', value: filter.boolValue }; } else if (filter.numberValue !== undefined) { - value = { case: "numberValue", value: filter.numberValue }; + value = { case: 'numberValue', value: Number(filter.numberValue) }; } else if (filter.stringValue !== undefined) { - value = { case: "stringValue", value: filter.stringValue }; + value = { case: 'stringValue', value: filter.stringValue }; } else { value = convertFilterValue(filter.value); } @@ -57,7 +61,7 @@ function transformFilter( return create(RQLFilterSchema, { name: fieldName, operator: filter.operator, - value, + value }); } @@ -66,27 +70,29 @@ function transformFilter( */ function transformSort( sort: DataTableSort[], - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLSort[] | undefined { if (!sort || sort.length === 0) { return undefined; } - return sort.map((s) => create(RQLSortSchema, { - ...s, - name: fieldNameMapping?.[s.name] ?? s.name, - })); + return sort.map(s => + create(RQLSortSchema, { + ...s, + name: fieldNameMapping?.[s.name] ?? s.name + }) + ); } export function transformDataTableQueryToRQLRequest( query: DataTableQuery, - options: TransformOptions = {}, + options: TransformOptions = {} ): RQLRequest { const { defaultLimit = 50, fieldNameMapping } = options; // Transform DataTable filters const filters: RQLFilter[] = query.filters?.length - ? query.filters.map((filter) => transformFilter(filter, fieldNameMapping)) + ? query.filters.map(filter => transformFilter(filter, fieldNameMapping)) : []; // Build the RQLRequest with snake_case properties @@ -96,7 +102,7 @@ export function transformDataTableQueryToRQLRequest( offset: query.offset || 0, limit: query.limit || defaultLimit, sort: transformSort(query.sort || [], fieldNameMapping) || [], - search: query.search || "", + search: query.search || '' }); return rqlRequest; diff --git a/web/sdk/admin/views/organizations/details/invoices/columns.tsx b/web/sdk/admin/views/organizations/details/invoices/columns.tsx index 536226461..3a34cfeb7 100644 --- a/web/sdk/admin/views/organizations/details/invoices/columns.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/columns.tsx @@ -1,4 +1,3 @@ -import { NULL_DATE } from "../../../../utils/constants"; import styles from "./invoices.module.css"; import dayjs from "dayjs"; import { DataTableColumnDef, Link, Amount } from "@raystack/apsara-v1"; @@ -32,65 +31,65 @@ export const getColumns = ({ SearchOrganizationInvoicesResponse_OrganizationInvoice, unknown >[] => [ - { - accessorKey: "createdAt", - header: "Billed on", - classNames: { - cell: styles["first-column"], - header: styles["first-column"], + { + accessorKey: "createdAt", + header: "Billed on", + classNames: { + cell: styles["first-column"], + header: styles["first-column"], + }, + cell: ({ getValue }) => { + const value = getValue() as TimeStamp; + const date = isNullTimestamp(value) + ? "-" + : dayjs(timestampToDate(value)).format("YYYY-MM-DD"); + return date; + }, + enableSorting: true, + enableColumnFilter: true, + filterType: "date", }, - cell: ({ getValue }) => { - const value = getValue() as TimeStamp; - const date = isNullTimestamp(value) - ? "-" - : dayjs(timestampToDate(value)).format("YYYY-MM-DD"); - return date; + { + accessorKey: "state", + header: "Status", + cell: ({ getValue }) => { + const value = getValue() as InvoiceStatusKey; + return InvoiceStatusesMap[value]; + }, + enableColumnFilter: true, + filterType: "select", + filterOptions: Object.entries(InvoiceStatusesMap).map(([key, value]) => ({ + label: value, + value: key, + })), + enableGrouping: true, + groupLabelsMap: InvoiceStatusesMap, + showGroupCount: true, + groupCountMap: groupCountMap["state"] || {}, + enableHiding: true, }, - enableSorting: true, - enableColumnFilter: true, - filterType: "date", - }, - { - accessorKey: "state", - header: "Status", - cell: ({ getValue }) => { - const value = getValue() as InvoiceStatusKey; - return InvoiceStatusesMap[value]; + { + accessorKey: "amount", + header: "Amount", + cell: ({ getValue, row }) => { + const value = Number(getValue()); + return ; + }, + enableSorting: true, + enableHiding: true, + enableColumnFilter: true, + filterType: "number", }, - enableColumnFilter: true, - filterType: "select", - filterOptions: Object.entries(InvoiceStatusesMap).map(([key, value]) => ({ - label: value, - value: key, - })), - enableGrouping: true, - groupLabelsMap: InvoiceStatusesMap, - showGroupCount: true, - groupCountMap: groupCountMap["state"] || {}, - enableHiding: true, - }, - { - accessorKey: "amount", - header: "Amount", - cell: ({ getValue, row }) => { - const value = Number(getValue()); - return ; + { + accessorKey: "invoiceLink", + header: "", + cell: ({ getValue }) => { + const value = getValue() as string; + return ( + + View Invoice + + ); + }, }, - enableSorting: true, - enableHiding: true, - enableColumnFilter: true, - filterType: "number", - }, - { - accessorKey: "invoiceLink", - header: "", - cell: ({ getValue }) => { - const value = getValue() as string; - return ( - - View Invoice - - ); - }, - }, -]; + ]; diff --git a/web/sdk/admin/views/organizations/details/invoices/index.tsx b/web/sdk/admin/views/organizations/details/invoices/index.tsx index 36e203830..c306c941f 100644 --- a/web/sdk/admin/views/organizations/details/invoices/index.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/index.tsx @@ -96,7 +96,7 @@ export function OrganizationInvoicesView() { isFetchingNextPage, fetchNextPage, hasNextPage, - isError, + isError } = useInfiniteQuery( FrontierServiceQueries.searchOrganizationInvoices, { id: organizationId, query: query }, @@ -115,7 +115,6 @@ export function OrganizationInvoicesView() { retryDelay: 1000, }, ); - const data = infiniteData?.pages?.flatMap(page => page.organizationInvoices) || []; const loading = (isLoading || isFetchingNextPage) && !isError; diff --git a/web/sdk/react/utils/transform-query.ts b/web/sdk/react/utils/transform-query.ts index b9de9fd02..99fb51763 100644 --- a/web/sdk/react/utils/transform-query.ts +++ b/web/sdk/react/utils/transform-query.ts @@ -1,10 +1,14 @@ -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; -import type { RQLRequest, RQLFilter, RQLSort } from "@raystack/proton/frontier"; -import { RQLRequestSchema, RQLFilterSchema, RQLSortSchema } from "@raystack/proton/frontier"; -import { create } from "@bufbuild/protobuf"; +import type { DataTableQuery, DataTableSort } from '@raystack/apsara-v1'; +import type { RQLRequest, RQLFilter, RQLSort } from '@raystack/proton/frontier'; +import { + RQLRequestSchema, + RQLFilterSchema, + RQLSortSchema +} from '@raystack/proton/frontier'; +import { create } from '@bufbuild/protobuf'; // Extract DataTableFilter type from DataTableQuery since it's not exported -type DataTableFilter = NonNullable[number]; +type DataTableFilter = NonNullable[number]; export interface TransformOptions { /** @@ -22,16 +26,16 @@ export interface TransformOptions { /** * Converts a filter value to the appropriate RQLFilter value format */ -function convertFilterValue(value: unknown): RQLFilter["value"] { +function convertFilterValue(value: unknown): RQLFilter['value'] { switch (typeof value) { - case "boolean": - return { case: "boolValue", value }; - case "number": - return { case: "numberValue", value }; - case "string": - return { case: "stringValue", value }; + case 'boolean': + return { case: 'boolValue', value }; + case 'number': + return { case: 'numberValue', value }; + case 'string': + return { case: 'stringValue', value }; default: - return { case: "stringValue", value: value == null ? "" : String(value) }; + return { case: 'stringValue', value: value == null ? '' : String(value) }; } } @@ -40,17 +44,17 @@ function convertFilterValue(value: unknown): RQLFilter["value"] { */ function transformFilter( filter: DataTableFilter, - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLFilter { // Priority: typed values > generic value field - let value: RQLFilter["value"]; + let value: RQLFilter['value']; if (filter.boolValue !== undefined) { - value = { case: "boolValue", value: filter.boolValue }; + value = { case: 'boolValue', value: filter.boolValue }; } else if (filter.numberValue !== undefined) { - value = { case: "numberValue", value: filter.numberValue }; + value = { case: 'numberValue', value: Number(filter.numberValue) }; } else if (filter.stringValue !== undefined) { - value = { case: "stringValue", value: filter.stringValue }; + value = { case: 'stringValue', value: filter.stringValue }; } else { value = convertFilterValue(filter.value); } @@ -60,7 +64,7 @@ function transformFilter( return create(RQLFilterSchema, { name: fieldName, operator: filter.operator, - value, + value }); } @@ -69,16 +73,18 @@ function transformFilter( */ function transformSort( sort: DataTableSort[], - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLSort[] | undefined { if (!sort || sort.length === 0) { return undefined; } - return sort.map((s) => create(RQLSortSchema, { - ...s, - name: fieldNameMapping?.[s.name] ?? s.name, - })); + return sort.map(s => + create(RQLSortSchema, { + ...s, + name: fieldNameMapping?.[s.name] ?? s.name + }) + ); } /** @@ -87,23 +93,25 @@ function transformSort( */ export function transformDataTableQueryToRQLRequest( query: DataTableQuery, - options: TransformOptions = {}, + options: TransformOptions = {} ): RQLRequest { const { defaultLimit = 50, fieldNameMapping } = options; // Transform DataTable filters const filters: RQLFilter[] = query.filters?.length - ? query.filters.map((filter) => transformFilter(filter, fieldNameMapping)) + ? query.filters.map(filter => transformFilter(filter, fieldNameMapping)) : []; // Build the RQLRequest with snake_case properties const rqlRequest = create(RQLRequestSchema, { filters, - groupBy: (query.group_by || []).map(field => fieldNameMapping?.[field] ?? field), + groupBy: (query.group_by || []).map( + field => fieldNameMapping?.[field] ?? field + ), offset: query.offset || 0, limit: query.limit || defaultLimit, sort: transformSort(query.sort || [], fieldNameMapping) || [], - search: query.search || "", + search: query.search || '' }); return rqlRequest; diff --git a/web/sdk/utils/transform-query.ts b/web/sdk/utils/transform-query.ts index 9d46e3a21..dece22ac9 100644 --- a/web/sdk/utils/transform-query.ts +++ b/web/sdk/utils/transform-query.ts @@ -1,10 +1,14 @@ -import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; -import type { RQLRequest, RQLFilter, RQLSort } from "@raystack/proton/frontier"; -import { RQLRequestSchema, RQLFilterSchema, RQLSortSchema } from "@raystack/proton/frontier"; -import { create } from "@bufbuild/protobuf"; +import type { DataTableQuery, DataTableSort } from '@raystack/apsara'; +import type { RQLRequest, RQLFilter, RQLSort } from '@raystack/proton/frontier'; +import { + RQLRequestSchema, + RQLFilterSchema, + RQLSortSchema +} from '@raystack/proton/frontier'; +import { create } from '@bufbuild/protobuf'; // Extract DataTableFilter type from DataTableQuery since it's not exported -type DataTableFilter = NonNullable[number]; +type DataTableFilter = NonNullable[number]; export interface TransformOptions { /** @@ -23,17 +27,17 @@ export interface TransformOptions { * Converts a filter value to the appropriate RQLFilter value format */ function convertFilterValue( - value: string | number | boolean | null | undefined, -): RQLFilter["value"] { + value: string | number | boolean | null | undefined +): RQLFilter['value'] { switch (typeof value) { - case "boolean": - return { case: "boolValue", value }; - case "number": - return { case: "numberValue", value }; - case "string": - return { case: "stringValue", value }; + case 'boolean': + return { case: 'boolValue', value }; + case 'number': + return { case: 'numberValue', value }; + case 'string': + return { case: 'stringValue', value }; default: - return { case: "stringValue", value: value ?? "" }; + return { case: 'stringValue', value: value ?? '' }; } } @@ -42,17 +46,17 @@ function convertFilterValue( */ function transformFilter( filter: DataTableFilter, - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLFilter { // Priority: typed values > generic value field - let value: RQLFilter["value"]; + let value: RQLFilter['value']; if (filter.boolValue !== undefined) { - value = { case: "boolValue", value: filter.boolValue }; + value = { case: 'boolValue', value: filter.boolValue }; } else if (filter.numberValue !== undefined) { - value = { case: "numberValue", value: filter.numberValue }; + value = { case: 'numberValue', value: Number(filter.numberValue) }; } else if (filter.stringValue !== undefined) { - value = { case: "stringValue", value: filter.stringValue }; + value = { case: 'stringValue', value: filter.stringValue }; } else { value = convertFilterValue(filter.value); } @@ -62,7 +66,7 @@ function transformFilter( return create(RQLFilterSchema, { name: fieldName, operator: filter.operator, - value, + value }); } @@ -71,16 +75,18 @@ function transformFilter( */ function transformSort( sort: DataTableSort[], - fieldNameMapping?: Record, + fieldNameMapping?: Record ): RQLSort[] | undefined { if (!sort || sort.length === 0) { return undefined; } - return sort.map((s) => create(RQLSortSchema, { - ...s, - name: fieldNameMapping?.[s.name] ?? s.name, - })); + return sort.map(s => + create(RQLSortSchema, { + ...s, + name: fieldNameMapping?.[s.name] ?? s.name + }) + ); } /** @@ -89,23 +95,25 @@ function transformSort( */ export function transformDataTableQueryToRQLRequest( query: DataTableQuery, - options: TransformOptions = {}, + options: TransformOptions = {} ): RQLRequest { const { defaultLimit = 50, fieldNameMapping } = options; // Transform DataTable filters const filters: RQLFilter[] = query.filters?.length - ? query.filters.map((filter) => transformFilter(filter, fieldNameMapping)) + ? query.filters.map(filter => transformFilter(filter, fieldNameMapping)) : []; // Build the RQLRequest with snake_case properties const rqlRequest = create(RQLRequestSchema, { filters, - groupBy: (query.group_by || []).map(field => fieldNameMapping?.[field] ?? field), + groupBy: (query.group_by || []).map( + field => fieldNameMapping?.[field] ?? field + ), offset: query.offset || 0, limit: query.limit || defaultLimit, sort: transformSort(query.sort || [], fieldNameMapping) || [], - search: query.search || "", + search: query.search || '' }); return rqlRequest; From c4a697b636077c60fb52a8ce1aca249baf33efb4 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Tue, 2 Jun 2026 12:40:51 +0530 Subject: [PATCH 04/12] fix: new org validations --- .../admin/views/organizations/list/create.tsx | 116 +++++++++++------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/web/sdk/admin/views/organizations/list/create.tsx b/web/sdk/admin/views/organizations/list/create.tsx index 83649ee8e..2646e8eab 100644 --- a/web/sdk/admin/views/organizations/list/create.tsx +++ b/web/sdk/admin/views/organizations/list/create.tsx @@ -11,7 +11,6 @@ import { Drawer, SidePanel, Text, - Label, } from "@raystack/apsara-v1"; import { Cross1Icon } from "@radix-ui/react-icons"; import { AvatarUpload } from "../../../../react/components/avatar-upload"; @@ -19,27 +18,40 @@ import { z } from "zod"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation } from "@connectrpc/connect-query"; +import { Code } from "@connectrpc/connect"; import { AdminServiceQueries } from "@raystack/proton/frontier"; const orgCreateSchema = z .object({ avatar: z.string().optional(), - title: z.string(), - name: z.string(), - orgOwnerEmail: z.string().email(), - size: z.string().transform((value) => parseInt(value)), - type: z.string(), + title: z.string().min(1, "Title is required"), + name: z + .string() + .min(1, "URL is required") + .regex( + /^[a-z0-9-]+$/, + "Use only lowercase letters, numbers, and hyphens", + ), + orgOwnerEmail: z + .string() + .min(1, "Owner email is required") + .email("Enter a valid email address"), + size: z + .string() + .min(1, "Size is required") + .refine( + (value) => Number.isInteger(Number(value)) && Number(value) > 0, + "Enter a valid size greater than 0", + ) + .transform((value) => parseInt(value)), + type: z.string().min(1, "Industry is required"), otherType: z.string().optional(), - country: z.string(), + country: z.string().min(1, "Country is required"), }) - .refine( - (data) => - data.type !== "other" || (data.type === "other" && data.otherType), - { - message: "otherType is required when type is 'other'.", - path: ["otherType"], - }, - ); + .refine((data) => data.type !== "other" || Boolean(data.otherType?.trim()), { + message: "Please specify the industry", + path: ["otherType"], + }); type OrgCreateSchema = z.infer; @@ -80,25 +92,32 @@ export function CreateOrganizationPanel({ watch, register, } = useForm({ - defaultValues: {}, + defaultValues: { + avatar: "", + title: "", + name: "", + orgOwnerEmail: "", + type: "", + otherType: "", + country: "", + }, resolver: zodResolver(orgCreateSchema), }); - const { - mutateAsync: createOrganization, - error: mutationError, - isPending, - } = useMutation(AdminServiceQueries.adminCreateOrganization); - - useEffect(() => { - if (mutationError) { - if (mutationError.message?.includes("already exists")) { - setError("name", { message: `${t.organization({ case: "capital" })} name already exists` }); - } else { - console.error("Unable to create new org:", mutationError); - } - } - }, [mutationError, setError, t]); + const { mutateAsync: createOrganization, isPending } = useMutation( + AdminServiceQueries.adminCreateOrganization, + { + onError: (error) => { + if (error?.code === Code.AlreadyExists) { + setError("name", { + message: `${t.organization({ case: "capital" })} name already exists`, + }); + } else { + console.error("Unable to create new org:", error); + } + }, + }, + ); async function onSubmit(data: OrgCreateSchema) { try { @@ -126,7 +145,7 @@ export function CreateOrganizationPanel({ } } - const showOtherTypeField = watch("type", "other") === "other"; + const showOtherTypeField = watch("type") === "other"; return ( !open && onClose()}> @@ -174,37 +193,45 @@ export function CreateOrganizationPanel({ ); }} /> - + - + - + { return ( - - + - + ); }} /> @@ -244,8 +271,11 @@ export function CreateOrganizationPanel({ control={control} render={({ field }) => { return ( - - + - + ); }} /> From 8f07a11f5c4d2725e2ead3a6a8d14ec8f0d2e496 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Tue, 2 Jun 2026 13:07:06 +0530 Subject: [PATCH 05/12] fix: admin issues --- web/apps/admin/package.json | 4 +- web/apps/client-demo/package.json | 2 +- web/pnpm-lock.yaml | 62 ++----------------- .../admin/views/organizations/list/create.tsx | 16 ++--- .../components/image-upload/image-upload.tsx | 5 +- 5 files changed, 16 insertions(+), 73 deletions(-) diff --git a/web/apps/admin/package.json b/web/apps/admin/package.json index 6c691984c..8d94ed72c 100644 --- a/web/apps/admin/package.json +++ b/web/apps/admin/package.json @@ -17,7 +17,7 @@ "@hookform/resolvers": "^3.0.1", "@radix-ui/react-form": "^0.1.8", "@radix-ui/react-icons": "^1.3.0", - "@raystack/apsara": "1.0.0-rc.8", + "@raystack/apsara": "1.0.0-rc.9", "@raystack/frontier": "workspace:^", "@raystack/proton": "0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e", "@stitches/react": "^1.2.8", @@ -53,4 +53,4 @@ "vite": "^4.5.9", "vite-plugin-svgr": "^4.3.0" } -} +} \ No newline at end of file diff --git a/web/apps/client-demo/package.json b/web/apps/client-demo/package.json index 1463546c8..f9ad2b697 100644 --- a/web/apps/client-demo/package.json +++ b/web/apps/client-demo/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@radix-ui/react-icons": "^1.3.0", - "@raystack/apsara": "1.0.0-rc.8", + "@raystack/apsara": "1.0.0-rc.9", "@raystack/frontier": "workspace:^", "react": "^19.2.1", "react-dom": "^19.2.1", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 75ff3c1b7..b7cf73960 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -55,8 +55,8 @@ importers: specifier: ^1.3.0 version: 1.3.2(react@19.2.4) '@raystack/apsara': - specifier: 1.0.0-rc.8 - version: 1.0.0-rc.8(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 1.0.0-rc.9 + version: 1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@raystack/frontier': specifier: workspace:^ version: link:../../sdk @@ -161,8 +161,8 @@ importers: specifier: ^1.3.0 version: 1.3.2(react@19.2.4) '@raystack/apsara': - specifier: 1.0.0-rc.8 - version: 1.0.0-rc.8(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 1.0.0-rc.9 + version: 1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@raystack/frontier': specifier: workspace:^ version: link:../../sdk @@ -610,16 +610,6 @@ packages: date-fns: optional: true - '@base-ui/utils@0.2.6': - resolution: {integrity: sha512-yQ+qeuqohwhsNpoYDqqXaLllYAkPCP4vYdDrVo8FQXaAPfHWm1pG/Vm+jmGTA5JFS0BAIjookyapuJFY8F9PIw==} - peerDependencies: - '@types/react': ^17 || ^18 || ^19 - react: ^17 || ^18 || ^19 - react-dom: ^17 || ^18 || ^19 - peerDependenciesMeta: - '@types/react': - optional: true - '@base-ui/utils@0.2.8': resolution: {integrity: sha512-jvOi+c+ftGlGotNcKnzPVg2IhCaDTB6/6R3JeqdjdXktuAJi3wKH9T7+svuaKh1mmfVU11UWzUZVH74JDfi/wQ==} peerDependencies: @@ -2240,17 +2230,6 @@ packages: '@types/react': optional: true - '@raystack/apsara@1.0.0-rc.8': - resolution: {integrity: sha512-eJz0HxTb/81Jv3/ThQhptDLI6PXzoISa3X6D+t8I46OzCkcC4A9swBzkgDBWYN4R2O01C8g8uxzXLyQXnXl3gQ==} - engines: {node: '>=22'} - peerDependencies: - '@types/react': ^19 - react: ^19 - react-dom: ^19 - peerDependenciesMeta: - '@types/react': - optional: true - '@raystack/apsara@1.0.0-rc.9': resolution: {integrity: sha512-RucfY0H0eoVmP594gYWltvmqUicqNPpiH2VPL4EWWhXIsj69NuZXu3i2lvUK7pvgGpRJmkzIg6AdiEhwdxj0pQ==} engines: {node: '>=22'} @@ -7846,17 +7825,6 @@ snapshots: '@types/react': 19.2.14 date-fns: 4.1.0 - '@base-ui/utils@0.2.6(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@babel/runtime': 7.28.6 - '@floating-ui/utils': 0.2.11 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - reselect: 5.1.1 - use-sync-external-store: 1.6.0(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@base-ui/utils@0.2.8(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 @@ -9567,28 +9535,6 @@ snapshots: transitivePeerDependencies: - '@types/react-dom' - '@raystack/apsara@1.0.0-rc.8(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@base-ui/react': 1.4.1(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@base-ui/utils': 0.2.6(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-icons': 1.3.2(react@19.2.4) - '@tanstack/match-sorter-utils': 8.19.4 - '@tanstack/react-table': 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tanstack/react-virtual': 3.13.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tanstack/table-core': 8.21.3 - class-variance-authority: 0.7.1 - color: 5.0.3 - dayjs: 1.11.19 - prism-react-renderer: 2.4.1(react@19.2.4) - react: 19.2.4 - react-day-picker: 9.14.0(react@19.2.4) - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - transitivePeerDependencies: - - '@date-fns/tz' - - date-fns - '@raystack/apsara@1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@base-ui/react': 1.4.1(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) diff --git a/web/sdk/admin/views/organizations/list/create.tsx b/web/sdk/admin/views/organizations/list/create.tsx index 2646e8eab..7e1379ae9 100644 --- a/web/sdk/admin/views/organizations/list/create.tsx +++ b/web/sdk/admin/views/organizations/list/create.tsx @@ -13,7 +13,7 @@ import { Text, } from "@raystack/apsara-v1"; import { Cross1Icon } from "@radix-ui/react-icons"; -import { AvatarUpload } from "../../../../react/components/avatar-upload"; +import { ImageUpload } from "../../../../react/components/image-upload"; import { z } from "zod"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -180,16 +180,10 @@ export function CreateOrganizationPanel({ control={control} render={({ field }) => { return ( - <> - - - Pick a logo for your {t.organization({ case: "lower" })} - - + + + Pick a logo for your {t.organization({ case: "lower" })} + ); }} /> diff --git a/web/sdk/react/components/image-upload/image-upload.tsx b/web/sdk/react/components/image-upload/image-upload.tsx index 623503858..5729a9ca1 100644 --- a/web/sdk/react/components/image-upload/image-upload.tsx +++ b/web/sdk/react/components/image-upload/image-upload.tsx @@ -172,6 +172,10 @@ export function ImageUpload({ const [showCropDialog, setShowCropDialog] = useState(false); function onUploadIconClick() { + // Reset so selecting the same file again still fires `change` and reopens the crop dialog. + if (inputRef.current) { + inputRef.current.value = ''; + } inputRef.current?.click(); } @@ -182,7 +186,6 @@ export function ImageUpload({ const imageUrl = URL.createObjectURL(file); setImgSrc(imageUrl); setShowCropDialog(true); - e.target.files = null; } } From ea55b6625e390e92e01daba2787032890201e9ae Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Tue, 2 Jun 2026 15:49:23 +0530 Subject: [PATCH 06/12] feat: single role in admin --- web/sdk/admin/assets/icons/DeleteIcon.tsx | 23 +++ .../organizations/details/members/columns.tsx | 49 +++-- .../organizations/details/members/index.tsx | 42 ++--- .../details/members/update-role.tsx | 127 +++++++++++++ .../details/projects/members/assign-role.tsx | 167 ------------------ .../details/projects/members/columns.tsx | 47 +++-- .../details/projects/members/index.tsx | 43 ++--- .../details/projects/members/update-role.tsx | 133 ++++++++++++++ 8 files changed, 382 insertions(+), 249 deletions(-) create mode 100644 web/sdk/admin/assets/icons/DeleteIcon.tsx create mode 100644 web/sdk/admin/views/organizations/details/members/update-role.tsx delete mode 100644 web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx create mode 100644 web/sdk/admin/views/organizations/details/projects/members/update-role.tsx diff --git a/web/sdk/admin/assets/icons/DeleteIcon.tsx b/web/sdk/admin/assets/icons/DeleteIcon.tsx new file mode 100644 index 000000000..c3f6439c0 --- /dev/null +++ b/web/sdk/admin/assets/icons/DeleteIcon.tsx @@ -0,0 +1,23 @@ +import type { SVGProps } from "react"; + +export function DeleteIcon(props: SVGProps) { + return ( + + + + ); +} + +export default DeleteIcon; diff --git a/web/sdk/admin/views/organizations/details/members/columns.tsx b/web/sdk/admin/views/organizations/details/members/columns.tsx index fbcc0130f..23dfd343b 100644 --- a/web/sdk/admin/views/organizations/details/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/members/columns.tsx @@ -6,14 +6,17 @@ import { Text, Menu, IconButton, + AlertDialog, } from "@raystack/apsara-v1"; import type { SearchOrganizationUsersResponse_OrganizationUser, Role, } from "@raystack/proton/frontier"; +import type { UpdateRolePayload } from "./update-role"; import styles from "./members.module.css"; import dayjs from "dayjs"; -import { DotsHorizontalIcon } from "@radix-ui/react-icons"; +import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons"; +import { DeleteIcon } from "~/admin/assets/icons/DeleteIcon"; import { isNullTimestamp, TimeStamp, @@ -28,9 +31,9 @@ const MemberStates = { interface getColumnsOptions { roles: Role[]; memberCount: number; - handleAssignRoleAction: ( - user: SearchOrganizationUsersResponse_OrganizationUser, - ) => void; + updateRoleHandle: ReturnType< + typeof AlertDialog.createHandle + >; handleRemoveMemberAction: ( user: SearchOrganizationUsersResponse_OrganizationUser, ) => void; @@ -39,7 +42,7 @@ interface getColumnsOptions { export const getColumns = ({ roles = [], memberCount, - handleAssignRoleAction, + updateRoleHandle, handleRemoveMemberAction, }: getColumnsOptions): DataTableColumnDef< SearchOrganizationUsersResponse_OrganizationUser, @@ -141,6 +144,11 @@ export const getColumns = ({ cell: ({ row }) => { // The last remaining member of an organization cannot be removed. const canRemoveMember = memberCount > 1; + const userRoleIds = row.original.roleIds || []; + // Only offer roles the member doesn't already have. + const excludedRoles = roles.filter( + (role) => role.id && !userRoleIds.includes(role.id), + ); return ( - handleAssignRoleAction(row.original)} - data-test-id="admin-assign-role-action" - > - Assign role... - + {excludedRoles.map((role) => ( + } + onClick={() => + updateRoleHandle.openWithPayload({ + user: row.original, + role, + }) + } + data-test-id={`admin-assign-role-${role.name}-action`} + > + Make {role.title} + + ))} {canRemoveMember && ( + } onClick={() => handleRemoveMemberAction(row.original)} data-test-id="admin-remove-member-action" + style={{ color: "var(--rs-color-foreground-danger-primary)" }} > - Remove... + Remove )} diff --git a/web/sdk/admin/views/organizations/details/members/index.tsx b/web/sdk/admin/views/organizations/details/members/index.tsx index 7de93a847..26762582a 100644 --- a/web/sdk/admin/views/organizations/details/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/members/index.tsx @@ -1,4 +1,4 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; +import { AlertDialog, DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; import { PageTitle } from "../../../../components/PageTitle"; import styles from "./members.module.css"; @@ -15,7 +15,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { UsersIcon } from '../../../../assets/icons/UsersIcon'; import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; import { OrganizationContext } from '../contexts/organization-context'; -import { AssignRole } from '../../../../components/AssignRole'; +import { UpdateRole, type UpdateRolePayload } from './update-role'; import { RemoveMember } from './remove-member'; import { getConnectNextPageParam, @@ -24,6 +24,8 @@ import { import { transformDataTableQueryToRQLRequest } from '~/utils/transform-query'; import { useDebounceValue } from 'usehooks-ts'; +const updateRoleDialogHandle = AlertDialog.createHandle(); + const DEFAULT_SORT: DataTableSort = { name: 'orgJoinedAt', order: 'desc' }; const INITIAL_QUERY: DataTableQuery = { offset: 0, @@ -78,10 +80,6 @@ export function OrganizationMembersView() { const organizationId = organization?.id || ""; - const [assignRoleConfig, setAssignRoleConfig] = useState<{ - isOpen: boolean; - user: SearchOrganizationUsersResponse_OrganizationUser | null; - }>({ isOpen: false, user: null }); const [removeMemberConfig, setRemoveMemberConfig] = useState<{ isOpen: boolean; user: SearchOrganizationUsersResponse_OrganizationUser | null; @@ -124,8 +122,9 @@ export function OrganizationMembersView() { ); const data = infiniteData?.pages?.flatMap(page => page.orgUsers) || []; - const memberCount = - infiniteData?.pages?.[0]?.pagination?.totalCount ?? data.length; + // The backend doesn't send total_count, so rely on the loaded rows. This is + // only used to prevent removing the last remaining member. + const memberCount = data.length; const loading = (isLoading || isFetchingNextPage) && !isError; const onTableQueryChange = (newQuery: DataTableQuery) => { @@ -146,16 +145,6 @@ export function OrganizationMembersView() { }; }, [setSearchVisibility, onSearchChange]); - function openAssignRoleDialog( - user: SearchOrganizationUsersResponse_OrganizationUser, - ) { - setAssignRoleConfig({ isOpen: true, user }); - } - - function closeAssignRoleDialog() { - setAssignRoleConfig({ isOpen: false, user: null }); - } - function openRemoveMemberDialog( user: SearchOrganizationUsersResponse_OrganizationUser, ) { @@ -169,7 +158,7 @@ export function OrganizationMembersView() { const columns = getColumns({ roles, memberCount, - handleAssignRoleAction: openAssignRoleDialog, + updateRoleHandle: updateRoleDialogHandle, handleRemoveMemberAction: openRemoveMemberDialog, }); @@ -185,7 +174,6 @@ export function OrganizationMembersView() { } async function updateMember() { - setAssignRoleConfig({ isOpen: false, user: null }); // Invalidate and refetch the query await invalidateMembersQuery(); } @@ -200,15 +188,11 @@ export function OrganizationMembersView() { return ( <> - {assignRoleConfig.isOpen && assignRoleConfig.user ? ( - - ) : null} + {removeMemberConfig.isOpen && removeMemberConfig.user ? ( >; + organizationId: string; + onRoleUpdate: () => void; +} + +export const UpdateRole = ({ + handle, + organizationId, + onRoleUpdate, +}: UpdateRoleProps) => { + return ( + + {({ payload: rawPayload }) => { + const payload = rawPayload as UpdateRolePayload | undefined; + return payload ? ( + handle.close()} + onRoleUpdate={onRoleUpdate} + /> + ) : null; + }} + + ); +}; + +function UpdateRoleContent({ + payload, + organizationId, + onClose, + onRoleUpdate, +}: { + payload: UpdateRolePayload; + organizationId: string; + onClose: () => void; + onRoleUpdate: () => void; +}) { + const { mutateAsync: setMemberRole, isPending } = useMutation( + FrontierServiceQueries.setOrganizationMemberRole, + ); + + async function onSubmit() { + try { + await setMemberRole( + create(SetOrganizationMemberRoleRequestSchema, { + orgId: organizationId, + userId: payload.user.id, + roleId: payload.role.id, + }), + ); + + onRoleUpdate(); + toastManager.add({ + title: "Role assigned successfully", + type: "success", + }); + onClose(); + } catch (error) { + toastManager.add({ + title: "Failed to assign role", + description: error instanceof ConnectError ? error.message : undefined, + type: "error", + }); + console.error(error); + } + } + + return ( + + + Update role + + + + This will grant additional permissions to the user based on the new + role. + + + + + + + + ); +} diff --git a/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx b/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx deleted file mode 100644 index f2e516388..000000000 --- a/web/sdk/admin/views/organizations/details/projects/members/assign-role.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import { - Button, - Dialog, - Flex, - Label, - Radio, - Text, - toastManager, -} from "@raystack/apsara-v1"; -import styles from "./members.module.css"; -import type { - SearchProjectUsersResponse_ProjectUser, - Role, -} from "@raystack/proton/frontier"; -import { - FrontierServiceQueries, - SetProjectMemberRoleRequestSchema, -} from "@raystack/proton/frontier"; -import { create } from "@bufbuild/protobuf"; -import { ConnectError } from "@connectrpc/connect"; -import { useMutation } from "@connectrpc/connect-query"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { z } from "zod"; -import { SCOPES } from "~/admin/utils/constants"; - -interface AssignRoleProps { - projectId: string; - roles: Role[]; - user?: SearchProjectUsersResponse_ProjectUser; - onRoleUpdate: (user: SearchProjectUsersResponse_ProjectUser) => void; - onClose: () => void; -} - -const formSchema = z.object({ - roleId: z.string().min(1, "A role must be selected"), -}); - -type FormData = z.infer; - -export const AssignRole = ({ - roles = [], - user, - projectId, - onRoleUpdate, - onClose, -}: AssignRoleProps) => { - const currentRoleId = user?.roleIds?.[0] || ""; - - const { - handleSubmit, - watch, - setValue, - formState: { isSubmitting, errors, isDirty }, - } = useForm({ - defaultValues: { - roleId: currentRoleId, - }, - resolver: zodResolver(formSchema), - }); - - const { mutateAsync: setProjectMemberRole } = useMutation( - FrontierServiceQueries.setProjectMemberRole, - ); - - const selectedRoleId = watch("roleId"); - - const onSubmit = async (data: FormData) => { - try { - await setProjectMemberRole( - create(SetProjectMemberRoleRequestSchema, { - projectId, - principalId: user?.id || "", - principalType: SCOPES.USER, - roleId: data.roleId, - }), - ); - - if (onRoleUpdate) { - onRoleUpdate({ - ...user, - roleIds: [data.roleId], - } as SearchProjectUsersResponse_ProjectUser); - } - - toastManager.add({ title: "Role assigned successfully", type: "success" }); - } catch (error) { - toastManager.add({ - title: "Failed to assign role", - description: error instanceof ConnectError ? error.message : undefined, - type: "error", - }); - console.error(error); - } - }; - - return ( - - - - Assign Role - -
- - - - Taking this action may result in changes in the role which might - lead to changes in access of the user. - - - setValue("roleId", value as string, { shouldDirty: true }) - } - > - - {roles.map((role) => { - const htmlId = `role-${role.id}`; - return ( - - - - - ); - })} - {errors.roleId && ( - {errors.roleId.message} - )} - - - - - - - Cancel - - } - /> - - -
-
-
- ); -}; diff --git a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx index e7ca55115..4ce66b1d5 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx @@ -9,18 +9,23 @@ import { Flex, getAvatarColor, Text, + AlertDialog, } from "@raystack/apsara-v1"; import type { DataTableColumnDef } from "@raystack/apsara-v1"; -import { DotsHorizontalIcon } from "@radix-ui/react-icons"; +import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons"; +import { DeleteIcon } from "~/admin/assets/icons/DeleteIcon"; +import type { UpdateRolePayload } from "./update-role"; interface getColumnsOptions { roles: Role[]; - handleAssignRoleAction: (user: SearchProjectUsersResponse_ProjectUser) => void; + updateRoleHandle: ReturnType< + typeof AlertDialog.createHandle + >; handleRemoveAction: (user: SearchProjectUsersResponse_ProjectUser) => void; } export const getColumns = ({ - handleAssignRoleAction, + updateRoleHandle, handleRemoveAction, roles = [], }: getColumnsOptions): DataTableColumnDef< @@ -86,6 +91,11 @@ export const getColumns = ({ cell: styles["table-action-column"], }, cell: ({ row }) => { + const userRoleIds = row.original.roleIds || []; + // Only offer roles the member doesn't already have. + const excludedRoles = roles.filter( + (role) => role.id && !userRoleIds.includes(role.id), + ); return ( } /> @@ -96,17 +106,34 @@ export const getColumns = ({ // @ts-ignore portal={false} > + {excludedRoles.map((role) => ( + } + onClick={() => + updateRoleHandle.openWithPayload({ + user: row.original, + role, + }) + } + data-test-id={`admin-assign-role-${role.name}-action`} + > + Make {role.title} + + ))} handleAssignRoleAction(row.original)} - data-test-id="admin-assign-role-action" - > - Assign role... - - + } onClick={() => handleRemoveAction(row.original)} data-test-id="admin-remove-user-action" + style={{ color: "var(--rs-color-foreground-danger-primary)" }} > - Remove user... + Remove user diff --git a/web/sdk/admin/views/organizations/details/projects/members/index.tsx b/web/sdk/admin/views/organizations/details/projects/members/index.tsx index 8a5dbdb11..54ce6a2f7 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/index.tsx @@ -1,4 +1,4 @@ -import { DataTable, Dialog, EmptyState, Flex } from "@raystack/apsara-v1"; +import { AlertDialog, DataTable, Dialog, EmptyState, Flex } from "@raystack/apsara-v1"; import type { DataTableQuery } from "@raystack/apsara-v1"; import { useCallback, useMemo, useState } from "react"; import Skeleton from "react-loading-skeleton"; @@ -16,7 +16,7 @@ import { useDebouncedState } from "@raystack/apsara-v1/hooks"; import styles from "./members.module.css"; import { UsersIcon } from "../../../../../assets/icons/UsersIcon"; import { getColumns } from "./columns"; -import { AssignRole } from "./assign-role"; +import { UpdateRole, type UpdateRolePayload } from "./update-role"; import { PROJECT_NAMESPACE } from "../../types"; import { RemoveMember } from "./remove-member"; import { AddMembersDropdown } from "./add-members-dropdown"; @@ -42,6 +42,8 @@ const INITIAL_QUERY: DataTableQuery = { limit: DEFAULT_PAGE_SIZE, }; +const updateRoleDialogHandle = AlertDialog.createHandle(); + export const ProjectMembersDialog = ({ projectId, onClose, @@ -60,11 +62,6 @@ export const ProjectMembersDialog = ({ 200, ); - const [assignRoleConfig, setAssignRoleConfig] = useState<{ - isOpen: boolean; - user: SearchProjectUsersResponse_ProjectUser | null; - }>({ isOpen: false, user: null }); - const [removeMemberConfig, setRemoveMemberConfig] = useState<{ isOpen: boolean; user: SearchProjectUsersResponse_ProjectUser | null; @@ -153,17 +150,6 @@ export const ProjectMembersDialog = ({ await refetch(); } - const openAssignRoleDialog = useCallback( - (user: SearchProjectUsersResponse_ProjectUser) => { - setAssignRoleConfig({ isOpen: true, user }); - }, - [], - ); - - const closeAssignRoleDialog = useCallback(() => { - setAssignRoleConfig({ isOpen: false, user: null }); - }, []); - const openRemoveMemberDialog = useCallback( (user: SearchProjectUsersResponse_ProjectUser) => { setRemoveMemberConfig({ isOpen: true, user }); @@ -179,10 +165,10 @@ export const ProjectMembersDialog = ({ () => getColumns({ roles: projectRoles, - handleAssignRoleAction: openAssignRoleDialog, + updateRoleHandle: updateRoleDialogHandle, handleRemoveAction: openRemoveMemberDialog, }), - [projectRoles, openAssignRoleDialog, openRemoveMemberDialog], + [projectRoles, openRemoveMemberDialog], ); async function removeMember(user: SearchProjectUsersResponse_ProjectUser) { @@ -190,9 +176,8 @@ export const ProjectMembersDialog = ({ setRemoveMemberConfig({ isOpen: false, user: null }); } - async function updateMember(user: SearchProjectUsersResponse_ProjectUser) { + async function updateMember() { await refetch(); - setAssignRoleConfig({ isOpen: false, user: null }); } const loading = isMembersLoading || isFetchingNextPage; @@ -200,15 +185,11 @@ export const ProjectMembersDialog = ({ return ( <> - {assignRoleConfig.isOpen && assignRoleConfig.user ? ( - - ) : null} + {removeMemberConfig.isOpen && removeMemberConfig.user ? ( >; + projectId: string; + onRoleUpdate: () => void; +} + +export const UpdateRole = ({ + handle, + projectId, + onRoleUpdate, +}: UpdateRoleProps) => { + return ( + + {({ payload: rawPayload }) => { + const payload = rawPayload as UpdateRolePayload | undefined; + return payload ? ( + handle.close()} + onRoleUpdate={onRoleUpdate} + /> + ) : null; + }} + + ); +}; + +function UpdateRoleContent({ + payload, + projectId, + onClose, + onRoleUpdate, +}: { + payload: UpdateRolePayload; + projectId: string; + onClose: () => void; + onRoleUpdate: () => void; +}) { + const { mutateAsync: setProjectMemberRole, isPending } = useMutation( + FrontierServiceQueries.setProjectMemberRole, + ); + + async function onSubmit() { + try { + await setProjectMemberRole( + create(SetProjectMemberRoleRequestSchema, { + projectId, + principalId: payload.user.id || "", + principalType: SCOPES.USER, + roleId: payload.role.id, + }), + ); + + onRoleUpdate(); + toastManager.add({ + title: "Role assigned successfully", + type: "success", + }); + onClose(); + } catch (error) { + toastManager.add({ + title: "Failed to assign role", + description: error instanceof ConnectError ? error.message : undefined, + type: "error", + }); + console.error(error); + } + } + + return ( + + + Update role + + + + This will grant additional permissions to the user based on the new + role. + + + + + + + + ); +} From 84d6cfff138c4ec6cb3474cfc68a3d943c18c6ff Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Thu, 4 Jun 2026 10:45:20 +0530 Subject: [PATCH 07/12] chore: remove old views and apsara --- web/apps/admin/package.json | 2 +- web/apps/client-demo/package.json | 2 +- web/pnpm-lock.yaml | 2653 ++++------------- web/sdk/admin/components/AssignRole.tsx | 2 +- web/sdk/admin/components/CustomField.tsx | 2 +- web/sdk/admin/components/PageHeader.tsx | 2 +- web/sdk/admin/components/SheetFooter.tsx | 2 +- web/sdk/admin/components/SheetHeader.tsx | 2 +- web/sdk/admin/views/admins/columns.tsx | 2 +- web/sdk/admin/views/admins/index.tsx | 2 +- web/sdk/admin/views/audit-logs/actor-cell.tsx | 2 +- web/sdk/admin/views/audit-logs/columns.tsx | 2 +- web/sdk/admin/views/audit-logs/index.tsx | 4 +- web/sdk/admin/views/audit-logs/navbar.tsx | 2 +- .../views/audit-logs/sidepanel-details.tsx | 4 +- .../views/audit-logs/sidepanel-list-id.tsx | 2 +- .../views/audit-logs/sidepanel-list-link.tsx | 2 +- .../views/audit-logs/sidepanel-log-dialog.tsx | 2 +- web/sdk/admin/views/invoices/columns.tsx | 2 +- web/sdk/admin/views/invoices/index.tsx | 2 +- web/sdk/admin/views/invoices/navbar.tsx | 2 +- .../organizations/details/apis/columns.tsx | 2 +- .../details/apis/details-dialog.tsx | 2 +- .../organizations/details/apis/index.tsx | 4 +- .../organizations/details/edit/billing.tsx | 2 +- .../views/organizations/details/edit/kyc.tsx | 2 +- .../details/edit/organization.tsx | 6 +- .../details/invoices/columns.tsx | 2 +- .../organizations/details/invoices/index.tsx | 4 +- .../details/layout/add-tokens-dialog.tsx | 2 +- .../organizations/details/layout/index.tsx | 4 +- .../details/layout/invite-users-dialog.tsx | 2 +- .../organizations/details/layout/navbar.tsx | 4 +- .../organizations/details/members/columns.tsx | 2 +- .../organizations/details/members/index.tsx | 4 +- .../details/members/remove-member.tsx | 2 +- .../details/members/update-role.tsx | 2 +- .../organizations/details/pat/columns.tsx | 2 +- .../pat/components/pat-details-dialog.tsx | 2 +- .../views/organizations/details/pat/index.tsx | 4 +- .../details/projects/columns.tsx | 4 +- .../organizations/details/projects/index.tsx | 2 +- .../projects/members/add-members-dropdown.tsx | 2 +- .../details/projects/members/columns.tsx | 4 +- .../details/projects/members/index.tsx | 6 +- .../projects/members/remove-member.tsx | 2 +- .../details/projects/members/update-role.tsx | 2 +- .../details/projects/rename-project.tsx | 2 +- .../projects/use-add-project-members.tsx | 2 +- .../details/security/block-organization.tsx | 2 +- .../details/security/domains-list.tsx | 2 +- .../organizations/details/security/index.tsx | 2 +- .../side-panel/billing-details-section.tsx | 2 +- .../details/side-panel/index.tsx | 2 +- .../details/side-panel/kyc-section.tsx | 4 +- .../side-panel/org-details-section.tsx | 2 +- .../side-panel/plan-details-section.tsx | 2 +- .../side-panel/tokens-details-section.tsx | 4 +- .../organizations/details/tokens/columns.tsx | 2 +- .../organizations/details/tokens/index.tsx | 6 +- .../views/organizations/list/columns.tsx | 2 +- .../admin/views/organizations/list/create.tsx | 2 +- .../admin/views/organizations/list/index.tsx | 6 +- .../admin/views/organizations/list/navbar.tsx | 4 +- web/sdk/admin/views/plans/columns.tsx | 2 +- web/sdk/admin/views/plans/details.tsx | 2 +- web/sdk/admin/views/plans/index.tsx | 2 +- .../views/preferences/PreferencesView.tsx | 2 +- web/sdk/admin/views/preferences/columns.tsx | 2 +- web/sdk/admin/views/preferences/details.tsx | 2 +- web/sdk/admin/views/preferences/index.tsx | 2 +- web/sdk/admin/views/products/columns.tsx | 2 +- web/sdk/admin/views/products/details.tsx | 2 +- web/sdk/admin/views/products/index.tsx | 2 +- .../admin/views/products/prices/columns.tsx | 4 +- web/sdk/admin/views/products/prices/index.tsx | 2 +- web/sdk/admin/views/roles/columns.tsx | 2 +- web/sdk/admin/views/roles/details.tsx | 2 +- web/sdk/admin/views/roles/index.tsx | 2 +- .../views/users/details/layout/layout.tsx | 2 +- .../details/layout/membership-dropdown.tsx | 2 +- .../views/users/details/layout/navbar.tsx | 4 +- .../details/layout/side-panel-details.tsx | 2 +- .../details/layout/side-panel-membership.tsx | 2 +- .../views/users/details/layout/side-panel.tsx | 2 +- .../users/details/layout/suspend-user.tsx | 2 +- .../users/details/security/block-user.tsx | 2 +- .../views/users/details/security/security.tsx | 2 +- .../users/details/security/sessions/index.tsx | 2 +- .../sessions/revoke-session-confirm.tsx | 2 +- .../sessions/revoke-session-final-confirm.tsx | 2 +- .../security/sessions/session-skeleton.tsx | 2 +- .../views/users/details/user-details.tsx | 2 +- web/sdk/admin/views/users/list/columns.tsx | 2 +- .../admin/views/users/list/invite-users.tsx | 2 +- web/sdk/admin/views/users/list/list.tsx | 6 +- web/sdk/admin/views/users/list/navbar.tsx | 2 +- .../admin/views/webhooks/webhooks/columns.tsx | 2 +- .../views/webhooks/webhooks/create/index.tsx | 2 +- .../views/webhooks/webhooks/delete/index.tsx | 2 +- .../admin/views/webhooks/webhooks/index.tsx | 2 +- .../views/webhooks/webhooks/update/index.tsx | 2 +- web/sdk/package.json | 13 +- web/sdk/react/client.ts | 58 - web/sdk/react/components/Container.tsx | 55 - web/sdk/react/components/Header.tsx | 36 - web/sdk/react/components/Layout/index.tsx | 24 - .../react/components/Layout/layout.module.css | 10 - .../auth-container/auth-container.tsx | 2 +- .../components/auth-header/auth-header.tsx | 2 +- .../auth-oidc-button/auth-oidc-button.tsx | 2 +- .../avatar-upload/avatar-upload.module.css | 60 - .../react/components/avatar-upload/index.tsx | 250 -- .../components/common/page-header/index.tsx | 35 - .../upcoming-plan-change-banner/index.tsx | 162 - .../styles.module.css | 15 - web/sdk/react/components/container.module.css | 36 - web/sdk/react/components/header.module.css | 9 - .../components/image-upload/image-upload.tsx | 2 +- web/sdk/react/components/index.ts | 1 - .../onboarding/magiclink-verify.tsx | 126 - .../react/components/onboarding/magiclink.tsx | 152 - web/sdk/react/components/onboarding/oidc.tsx | 31 - .../onboarding/onboarding.module.css | 98 - .../react/components/onboarding/signin.tsx | 93 - .../react/components/onboarding/signup.tsx | 89 - .../react/components/onboarding/subscribe.tsx | 206 -- .../react/components/onboarding/updates.tsx | 107 - .../organization/api-keys/index.tsx | 19 - .../api-keys/service-user/index.tsx | 18 - .../components/organization/billing/index.tsx | 14 - .../react/components/organization/create.tsx | 114 - .../organization/domain/add-domain.tsx | 141 - .../components/organization/domain/delete.tsx | 184 -- .../organization/domain/domain.columns.tsx | 115 - .../organization/domain/domain.module.css | 23 - .../components/organization/domain/index.tsx | 181 -- .../organization/domain/verify-domain.tsx | 168 -- .../components/organization/general/index.tsx | 10 - .../components/organization/members/index.tsx | 7 - .../organization/organization.module.css | 43 - .../components/organization/plans/index.tsx | 7 - .../organization/preferences/index.tsx | 10 - .../react/components/organization/profile.tsx | 98 - .../components/organization/project/index.tsx | 16 - .../organization/project/project.tsx | 16 - .../react/components/organization/routes.tsx | 285 -- .../organization/security/index.tsx | 7 - .../organization/sessions/index.tsx | 9 - .../components/organization/shared/types.ts | 7 - .../organization/sidebar/helpers.ts | 113 - .../components/organization/sidebar/index.tsx | 212 -- .../organization/sidebar/sidebar.module.css | 22 - .../components/organization/styles.module.css | 28 - .../components/organization/teams/index.tsx | 12 - .../components/organization/teams/team.tsx | 16 - .../components/organization/tokens/index.tsx | 7 - .../components/organization/user/index.tsx | 7 - .../view-container/view-container.tsx | 2 +- .../components/view-header/view-header.tsx | 2 +- web/sdk/react/components/window/index.tsx | 78 - .../react/components/window/window.module.css | 20 - web/sdk/react/contexts/FrontierProvider.tsx | 4 +- web/sdk/react/hooks/useSessions.ts | 13 +- web/sdk/react/hooks/useSessionsV1.ts | 116 - web/sdk/react/hooks/useTokens.ts | 7 +- web/sdk/react/hooks/useTokensV1.ts | 54 - web/sdk/react/index.ts | 45 +- web/sdk/react/utils/transform-query.ts | 2 +- web/sdk/react/views-new/billing/index.ts | 2 - web/sdk/react/views-new/general/index.ts | 2 - web/sdk/react/views-new/members/index.ts | 2 - .../react/views-new/plans/helpers/index.ts | 54 - web/sdk/react/views-new/plans/index.ts | 1 - web/sdk/react/views-new/preferences/index.ts | 2 - web/sdk/react/views-new/profile/index.ts | 1 - web/sdk/react/views-new/projects/index.ts | 3 - web/sdk/react/views-new/security/index.ts | 2 - web/sdk/react/views-new/sessions/index.ts | 2 - web/sdk/react/views-new/teams/index.ts | 3 - web/sdk/react/views-new/tokens/index.ts | 1 - .../details/add-service-user-token.tsx | 92 - .../delete-service-user-key-dialog.tsx | 127 - web/sdk/react/views/api-keys/details/index.ts | 8 - .../manage-service-user-projects-dialog.tsx | 283 -- .../details/service-user-detail-page.tsx | 270 -- .../api-keys/details/service-user.module.css | 93 - .../api-keys/hooks/useServiceUserTokens.ts | 89 - web/sdk/react/views/api-keys/index.ts | 2 - .../list/add-service-account-dialog.tsx | 317 -- .../views/api-keys/list/api-keys-columns.tsx | 61 - .../api-keys/list/api-keys-list-page.tsx | 305 -- .../views/api-keys/list/api-keys.module.css | 64 - .../list/delete-service-account-dialog.tsx | 127 - web/sdk/react/views/api-keys/list/index.ts | 8 - .../auth/magic-link-verify/index.ts | 0 .../magic-link-verify-view.module.css | 0 .../magic-link-verify-view.tsx | 2 +- .../auth/magic-link/index.ts | 0 .../magic-link/magic-link-view.module.css | 0 .../auth/magic-link/magic-link-view.tsx | 2 +- .../auth/sign-in/index.ts | 0 .../auth/sign-in/sign-in-view.module.css | 0 .../auth/sign-in/sign-in-view.tsx | 2 +- .../auth/sign-up/index.ts | 0 .../auth/sign-up/sign-up-view.module.css | 0 .../auth/sign-up/sign-up-view.tsx | 2 +- .../auth/subscribe/index.ts | 0 .../auth/subscribe/subscribe-view.module.css | 0 .../auth/subscribe/subscribe-view.tsx | 2 +- .../auth/updates/index.ts | 0 .../auth/updates/updates-view.module.css | 0 .../auth/updates/updates-view.tsx | 2 +- web/sdk/react/views/billing/billing-page.tsx | 317 -- .../billing/billing-view.module.css | 0 .../billing/billing-view.tsx | 2 +- .../react/views/billing/billing.module.css | 87 - .../components/billing-details-card.tsx | 2 +- .../confirm-cycle-switch-dialog.tsx | 2 +- .../billing/components/invoices.tsx | 4 +- .../billing/components/payment-issue.tsx | 2 +- .../components/payment-method-card.tsx | 2 +- .../components/upcoming-billing-cycle.tsx | 2 +- .../upcoming-plan-change-banner.tsx | 2 +- .../billing/confirm-cycle-switch-dialog.tsx | 193 -- web/sdk/react/views/billing/index.ts | 7 +- .../react/views/billing/invoices/index.tsx | 123 - .../views/billing/invoices/invoice.module.css | 13 - web/sdk/react/views/billing/payment-issue.tsx | 61 - .../react/views/billing/payment-method.tsx | 144 - .../views/billing/upcoming-billing-cycle.tsx | 277 -- .../create-organization-view.module.css | 0 .../create-organization-view.tsx | 2 +- .../create-organization/index.ts | 0 .../components/delete-organization-dialog.tsx | 2 +- .../general/delete-organization-dialog.tsx | 148 - .../views/general/general-organization.tsx | 204 -- web/sdk/react/views/general/general-page.tsx | 127 - .../general/general-view.module.css | 0 .../general/general-view.tsx | 2 +- .../react/views/general/general.module.css | 52 - web/sdk/react/views/general/index.ts | 10 +- .../components/invite-member-dialog.tsx | 2 +- .../components/member-columns.module.css | 0 .../members/components/member-columns.tsx | 2 +- .../components/remove-member-dialog.tsx | 2 +- .../members/components/update-role-dialog.tsx | 2 +- web/sdk/react/views/members/index.ts | 10 +- .../views/members/invite-member-dialog.tsx | 305 -- .../react/views/members/member-columns.tsx | 201 -- web/sdk/react/views/members/member-types.ts | 22 - web/sdk/react/views/members/members-page.tsx | 233 -- .../members/members-view.module.css | 0 .../members/members-view.tsx | 2 +- .../react/views/members/members.module.css | 32 - .../views/members/remove-member-dialog.tsx | 140 - .../pat/components/pat-columns.tsx | 2 +- .../pat/components/pat-created-dialog.tsx | 2 +- .../pat/components/pat-form-dialog.tsx | 2 +- .../components/pat-project-chips.module.css | 0 .../pat/components/pat-project-chips.tsx | 2 +- .../regenerate-pat-dialog.module.css | 0 .../pat/components/regenerate-pat-dialog.tsx | 2 +- .../pat/components/revoke-pat-dialog.tsx | 2 +- .../pat/components/token-cell.tsx | 2 +- .../react/{views-new => views}/pat/index.ts | 0 .../pat/pat-details-view.module.css | 0 .../pat/pat-details-view.tsx | 2 +- .../pat/pat-view.module.css | 0 .../{views-new => views}/pat/pat-view.tsx | 6 +- .../react/{views-new => views}/pat/utils.ts | 0 .../components/confirm-plan-change-dialog.tsx | 4 +- .../plans/components/feature-table.module.css | 0 .../plans/components/feature-table.tsx | 2 +- .../plans/components/plan-card.module.css | 0 .../plans/components/plan-card.tsx | 2 +- .../plans/confirm-plan-change-dialog.tsx | 261 -- .../react/views/plans/helpers/helpers.test.ts | 558 ---- web/sdk/react/views/plans/helpers/index.ts | 6 +- .../plans/hooks/use-plans.tsx | 2 +- web/sdk/react/views/plans/hooks/usePlans.tsx | 315 -- web/sdk/react/views/plans/index.ts | 6 +- web/sdk/react/views/plans/plans-header.tsx | 44 - web/sdk/react/views/plans/plans-page.tsx | 215 -- .../plans/plans-view.module.css | 0 .../{views-new => views}/plans/plans-view.tsx | 4 +- web/sdk/react/views/plans/plans.module.css | 119 - web/sdk/react/views/plans/pricing-column.tsx | 442 --- .../preferences/components/preference-row.tsx | 2 +- .../components/preferences-row.module.css | 0 web/sdk/react/views/preferences/index.ts | 3 +- .../views/preferences/preferences-page.tsx | 188 -- .../preferences/preferences-view.module.css | 0 .../preferences/preferences-view.tsx | 6 +- .../views/preferences/preferences.types.ts | 12 - web/sdk/react/views/profile/index.ts | 3 +- web/sdk/react/views/profile/profile-page.tsx | 20 - .../profile/profile-view.module.css | 0 .../profile/profile-view.tsx | 2 +- .../react/views/profile/update-profile.tsx | 171 -- .../projects/components/add-member-menu.tsx | 4 +- .../components/add-project-dialog.tsx | 4 +- .../components/delete-project-dialog.tsx | 4 +- .../components/edit-project-dialog.tsx | 4 +- .../components/member-columns.module.css | 0 .../projects/components/member-columns.tsx | 2 +- .../components/members-cell.module.css | 0 .../projects/components/members-cell.tsx | 2 +- .../components/project-columns.module.css | 0 .../projects/components/project-columns.tsx | 2 +- .../components/remove-member-dialog.tsx | 4 +- .../components/update-role-dialog.tsx | 2 +- .../details/delete-project-dialog.tsx | 196 -- web/sdk/react/views/projects/details/index.ts | 9 - .../projects/details/project-detail-page.tsx | 266 -- .../details/project-detail.module.css | 8 - .../projects/details/project-general.tsx | 236 -- .../details/project-member-columns.tsx | 220 -- .../details/project-members.module.css | 47 - .../projects/details/project-members.tsx | 414 --- .../details/remove-project-member-dialog.tsx | 153 - web/sdk/react/views/projects/index.ts | 18 +- .../projects/list/add-project-dialog.tsx | 164 - web/sdk/react/views/projects/list/index.ts | 6 - .../views/projects/list/projects-columns.tsx | 113 - .../projects/list/projects-list-page.tsx | 284 -- .../views/projects/list/projects.module.css | 24 - .../projects/project-details-view.module.css | 0 .../projects/project-details-view.tsx | 4 +- .../projects/projects-view.module.css | 0 .../projects/projects-view.tsx | 4 +- .../security/components/add-domain-dialog.tsx | 2 +- .../components/delete-domain-dialog.tsx | 2 +- .../components/verify-domain-dialog.tsx | 2 +- web/sdk/react/views/security/index.ts | 4 +- .../react/views/security/security-page.tsx | 191 -- .../react/views/security/security-types.ts | 8 - .../security/security-view.module.css | 0 .../security/security-view.tsx | 2 +- .../components/add-service-account-dialog.tsx | 2 +- .../components/add-token-form.tsx | 2 +- .../delete-service-account-dialog.tsx | 2 +- .../manage-project-access-dialog.tsx | 4 +- .../components/revoke-token-dialog.tsx | 2 +- .../service-account-columns.module.css | 0 .../components/service-account-columns.tsx | 2 +- .../hooks/useServiceUserTokens.ts | 0 .../service-accounts/index.ts | 0 .../service-account-details-view.module.css | 0 .../service-account-details-view.tsx | 2 +- .../service-accounts-view.module.css | 0 .../service-accounts-view.tsx | 2 +- .../revoke-session-confirm-dialog.tsx | 2 +- .../revoke-session-dialog.module.css | 0 .../components/revoke-session-dialog.tsx | 4 +- web/sdk/react/views/sessions/index.ts | 7 +- .../views/sessions/revoke-session-dialog.tsx | 161 - .../sessions/revoke-session-final-confirm.tsx | 88 - .../react/views/sessions/session-skeleton.tsx | 22 - .../react/views/sessions/sessions-page.tsx | 133 - .../sessions/sessions-view.module.css | 0 .../sessions/sessions-view.tsx | 4 +- .../react/views/sessions/sessions.module.css | 45 - .../teams/components/add-member-menu.tsx | 4 +- .../teams/components/add-team-dialog.tsx | 4 +- .../teams/components/delete-team-dialog.tsx | 4 +- .../teams/components/edit-team-dialog.tsx | 4 +- .../components/member-columns.module.css | 0 .../teams/components/member-columns.tsx | 2 +- .../teams/components/remove-member-dialog.tsx | 4 +- .../teams/components/team-columns.module.css | 0 .../teams/components/team-columns.tsx | 2 +- .../teams/details/delete-team-dialog.tsx | 205 -- web/sdk/react/views/teams/details/index.ts | 9 - .../details/invite-team-member-dialog.tsx | 340 --- .../views/teams/details/team-detail-page.tsx | 197 -- .../teams/details/team-detail.module.css | 8 - .../views/teams/details/team-general.tsx | 218 -- .../teams/details/team-member-columns.tsx | 225 -- .../teams/details/team-members.module.css | 54 - .../views/teams/details/team-members.tsx | 345 --- web/sdk/react/views/teams/index.ts | 17 +- .../views/teams/list/add-team-dialog.tsx | 153 - web/sdk/react/views/teams/list/index.ts | 6 - .../react/views/teams/list/teams-columns.tsx | 99 - .../views/teams/list/teams-list-page.tsx | 273 -- .../react/views/teams/list/teams.module.css | 24 - .../teams/team-details-view.module.css | 0 .../teams/team-details-view.tsx | 4 +- .../teams/teams-view.module.css | 0 .../{views-new => views}/teams/teams-view.tsx | 4 +- .../react/views/tokens/add-tokens-dialog.tsx | 224 -- .../tokens/components/add-tokens-dialog.tsx | 3 +- .../tokens/components/columns.tsx | 4 +- web/sdk/react/views/tokens/index.ts | 6 +- web/sdk/react/views/tokens/token.module.css | 46 - web/sdk/react/views/tokens/tokens-page.tsx | 239 -- .../tokens/tokens-view.module.css | 0 .../tokens/tokens-view.tsx | 8 +- .../views/tokens/transactions/columns.tsx | 101 - .../react/views/tokens/transactions/index.tsx | 54 - web/sdk/tsup.config.ts | 19 +- web/sdk/utils/transform-query.ts | 6 +- 403 files changed, 822 insertions(+), 18895 deletions(-) delete mode 100644 web/sdk/react/client.ts delete mode 100644 web/sdk/react/components/Container.tsx delete mode 100644 web/sdk/react/components/Header.tsx delete mode 100644 web/sdk/react/components/Layout/index.tsx delete mode 100644 web/sdk/react/components/Layout/layout.module.css delete mode 100644 web/sdk/react/components/avatar-upload/avatar-upload.module.css delete mode 100644 web/sdk/react/components/avatar-upload/index.tsx delete mode 100644 web/sdk/react/components/common/page-header/index.tsx delete mode 100644 web/sdk/react/components/common/upcoming-plan-change-banner/index.tsx delete mode 100644 web/sdk/react/components/common/upcoming-plan-change-banner/styles.module.css delete mode 100644 web/sdk/react/components/container.module.css delete mode 100644 web/sdk/react/components/header.module.css delete mode 100644 web/sdk/react/components/index.ts delete mode 100644 web/sdk/react/components/onboarding/magiclink-verify.tsx delete mode 100644 web/sdk/react/components/onboarding/magiclink.tsx delete mode 100644 web/sdk/react/components/onboarding/oidc.tsx delete mode 100644 web/sdk/react/components/onboarding/onboarding.module.css delete mode 100644 web/sdk/react/components/onboarding/signin.tsx delete mode 100644 web/sdk/react/components/onboarding/signup.tsx delete mode 100644 web/sdk/react/components/onboarding/subscribe.tsx delete mode 100644 web/sdk/react/components/onboarding/updates.tsx delete mode 100644 web/sdk/react/components/organization/api-keys/index.tsx delete mode 100644 web/sdk/react/components/organization/api-keys/service-user/index.tsx delete mode 100644 web/sdk/react/components/organization/billing/index.tsx delete mode 100644 web/sdk/react/components/organization/create.tsx delete mode 100644 web/sdk/react/components/organization/domain/add-domain.tsx delete mode 100644 web/sdk/react/components/organization/domain/delete.tsx delete mode 100644 web/sdk/react/components/organization/domain/domain.columns.tsx delete mode 100644 web/sdk/react/components/organization/domain/domain.module.css delete mode 100644 web/sdk/react/components/organization/domain/index.tsx delete mode 100644 web/sdk/react/components/organization/domain/verify-domain.tsx delete mode 100644 web/sdk/react/components/organization/general/index.tsx delete mode 100644 web/sdk/react/components/organization/members/index.tsx delete mode 100644 web/sdk/react/components/organization/organization.module.css delete mode 100644 web/sdk/react/components/organization/plans/index.tsx delete mode 100644 web/sdk/react/components/organization/preferences/index.tsx delete mode 100644 web/sdk/react/components/organization/profile.tsx delete mode 100644 web/sdk/react/components/organization/project/index.tsx delete mode 100644 web/sdk/react/components/organization/project/project.tsx delete mode 100644 web/sdk/react/components/organization/routes.tsx delete mode 100644 web/sdk/react/components/organization/security/index.tsx delete mode 100644 web/sdk/react/components/organization/sessions/index.tsx delete mode 100644 web/sdk/react/components/organization/shared/types.ts delete mode 100644 web/sdk/react/components/organization/sidebar/helpers.ts delete mode 100644 web/sdk/react/components/organization/sidebar/index.tsx delete mode 100644 web/sdk/react/components/organization/sidebar/sidebar.module.css delete mode 100644 web/sdk/react/components/organization/styles.module.css delete mode 100644 web/sdk/react/components/organization/teams/index.tsx delete mode 100644 web/sdk/react/components/organization/teams/team.tsx delete mode 100644 web/sdk/react/components/organization/tokens/index.tsx delete mode 100644 web/sdk/react/components/organization/user/index.tsx delete mode 100644 web/sdk/react/components/window/index.tsx delete mode 100644 web/sdk/react/components/window/window.module.css delete mode 100644 web/sdk/react/hooks/useSessionsV1.ts delete mode 100644 web/sdk/react/hooks/useTokensV1.ts delete mode 100644 web/sdk/react/views-new/billing/index.ts delete mode 100644 web/sdk/react/views-new/general/index.ts delete mode 100644 web/sdk/react/views-new/members/index.ts delete mode 100644 web/sdk/react/views-new/plans/helpers/index.ts delete mode 100644 web/sdk/react/views-new/plans/index.ts delete mode 100644 web/sdk/react/views-new/preferences/index.ts delete mode 100644 web/sdk/react/views-new/profile/index.ts delete mode 100644 web/sdk/react/views-new/projects/index.ts delete mode 100644 web/sdk/react/views-new/security/index.ts delete mode 100644 web/sdk/react/views-new/sessions/index.ts delete mode 100644 web/sdk/react/views-new/teams/index.ts delete mode 100644 web/sdk/react/views-new/tokens/index.ts delete mode 100644 web/sdk/react/views/api-keys/details/add-service-user-token.tsx delete mode 100644 web/sdk/react/views/api-keys/details/delete-service-user-key-dialog.tsx delete mode 100644 web/sdk/react/views/api-keys/details/index.ts delete mode 100644 web/sdk/react/views/api-keys/details/manage-service-user-projects-dialog.tsx delete mode 100644 web/sdk/react/views/api-keys/details/service-user-detail-page.tsx delete mode 100644 web/sdk/react/views/api-keys/details/service-user.module.css delete mode 100644 web/sdk/react/views/api-keys/hooks/useServiceUserTokens.ts delete mode 100644 web/sdk/react/views/api-keys/index.ts delete mode 100644 web/sdk/react/views/api-keys/list/add-service-account-dialog.tsx delete mode 100644 web/sdk/react/views/api-keys/list/api-keys-columns.tsx delete mode 100644 web/sdk/react/views/api-keys/list/api-keys-list-page.tsx delete mode 100644 web/sdk/react/views/api-keys/list/api-keys.module.css delete mode 100644 web/sdk/react/views/api-keys/list/delete-service-account-dialog.tsx delete mode 100644 web/sdk/react/views/api-keys/list/index.ts rename web/sdk/react/{views-new => views}/auth/magic-link-verify/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/magic-link-verify/magic-link-verify-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/magic-link-verify/magic-link-verify-view.tsx (99%) rename web/sdk/react/{views-new => views}/auth/magic-link/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/magic-link/magic-link-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/magic-link/magic-link-view.tsx (99%) rename web/sdk/react/{views-new => views}/auth/sign-in/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/sign-in/sign-in-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/sign-in/sign-in-view.tsx (97%) rename web/sdk/react/{views-new => views}/auth/sign-up/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/sign-up/sign-up-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/sign-up/sign-up-view.tsx (97%) rename web/sdk/react/{views-new => views}/auth/subscribe/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/subscribe/subscribe-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/subscribe/subscribe-view.tsx (99%) rename web/sdk/react/{views-new => views}/auth/updates/index.ts (100%) rename web/sdk/react/{views-new => views}/auth/updates/updates-view.module.css (100%) rename web/sdk/react/{views-new => views}/auth/updates/updates-view.tsx (99%) delete mode 100644 web/sdk/react/views/billing/billing-page.tsx rename web/sdk/react/{views-new => views}/billing/billing-view.module.css (100%) rename web/sdk/react/{views-new => views}/billing/billing-view.tsx (99%) delete mode 100644 web/sdk/react/views/billing/billing.module.css rename web/sdk/react/{views-new => views}/billing/components/billing-details-card.tsx (99%) rename web/sdk/react/{views-new => views}/billing/components/confirm-cycle-switch-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/billing/components/invoices.tsx (99%) rename web/sdk/react/{views-new => views}/billing/components/payment-issue.tsx (96%) rename web/sdk/react/{views-new => views}/billing/components/payment-method-card.tsx (99%) rename web/sdk/react/{views-new => views}/billing/components/upcoming-billing-cycle.tsx (99%) rename web/sdk/react/{views-new => views}/billing/components/upcoming-plan-change-banner.tsx (99%) delete mode 100644 web/sdk/react/views/billing/confirm-cycle-switch-dialog.tsx delete mode 100644 web/sdk/react/views/billing/invoices/index.tsx delete mode 100644 web/sdk/react/views/billing/invoices/invoice.module.css delete mode 100644 web/sdk/react/views/billing/payment-issue.tsx delete mode 100644 web/sdk/react/views/billing/payment-method.tsx delete mode 100644 web/sdk/react/views/billing/upcoming-billing-cycle.tsx rename web/sdk/react/{views-new => views}/create-organization/create-organization-view.module.css (100%) rename web/sdk/react/{views-new => views}/create-organization/create-organization-view.tsx (99%) rename web/sdk/react/{views-new => views}/create-organization/index.ts (100%) rename web/sdk/react/{views-new => views}/general/components/delete-organization-dialog.tsx (99%) delete mode 100644 web/sdk/react/views/general/delete-organization-dialog.tsx delete mode 100644 web/sdk/react/views/general/general-organization.tsx delete mode 100644 web/sdk/react/views/general/general-page.tsx rename web/sdk/react/{views-new => views}/general/general-view.module.css (100%) rename web/sdk/react/{views-new => views}/general/general-view.tsx (99%) delete mode 100644 web/sdk/react/views/general/general.module.css rename web/sdk/react/{views-new => views}/members/components/invite-member-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/members/components/member-columns.module.css (100%) rename web/sdk/react/{views-new => views}/members/components/member-columns.tsx (99%) rename web/sdk/react/{views-new => views}/members/components/remove-member-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/members/components/update-role-dialog.tsx (99%) delete mode 100644 web/sdk/react/views/members/invite-member-dialog.tsx delete mode 100644 web/sdk/react/views/members/member-columns.tsx delete mode 100644 web/sdk/react/views/members/member-types.ts delete mode 100644 web/sdk/react/views/members/members-page.tsx rename web/sdk/react/{views-new => views}/members/members-view.module.css (100%) rename web/sdk/react/{views-new => views}/members/members-view.tsx (99%) delete mode 100644 web/sdk/react/views/members/members.module.css delete mode 100644 web/sdk/react/views/members/remove-member-dialog.tsx rename web/sdk/react/{views-new => views}/pat/components/pat-columns.tsx (99%) rename web/sdk/react/{views-new => views}/pat/components/pat-created-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/pat/components/pat-form-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/pat/components/pat-project-chips.module.css (100%) rename web/sdk/react/{views-new => views}/pat/components/pat-project-chips.tsx (97%) rename web/sdk/react/{views-new => views}/pat/components/regenerate-pat-dialog.module.css (100%) rename web/sdk/react/{views-new => views}/pat/components/regenerate-pat-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/pat/components/revoke-pat-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/pat/components/token-cell.tsx (97%) rename web/sdk/react/{views-new => views}/pat/index.ts (100%) rename web/sdk/react/{views-new => views}/pat/pat-details-view.module.css (100%) rename web/sdk/react/{views-new => views}/pat/pat-details-view.tsx (99%) rename web/sdk/react/{views-new => views}/pat/pat-view.module.css (100%) rename web/sdk/react/{views-new => views}/pat/pat-view.tsx (98%) rename web/sdk/react/{views-new => views}/pat/utils.ts (100%) rename web/sdk/react/{views-new => views}/plans/components/confirm-plan-change-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/plans/components/feature-table.module.css (100%) rename web/sdk/react/{views-new => views}/plans/components/feature-table.tsx (98%) rename web/sdk/react/{views-new => views}/plans/components/plan-card.module.css (100%) rename web/sdk/react/{views-new => views}/plans/components/plan-card.tsx (99%) delete mode 100644 web/sdk/react/views/plans/confirm-plan-change-dialog.tsx delete mode 100644 web/sdk/react/views/plans/helpers/helpers.test.ts rename web/sdk/react/{views-new => views}/plans/hooks/use-plans.tsx (99%) delete mode 100644 web/sdk/react/views/plans/hooks/usePlans.tsx delete mode 100644 web/sdk/react/views/plans/plans-header.tsx delete mode 100644 web/sdk/react/views/plans/plans-page.tsx rename web/sdk/react/{views-new => views}/plans/plans-view.module.css (100%) rename web/sdk/react/{views-new => views}/plans/plans-view.tsx (97%) delete mode 100644 web/sdk/react/views/plans/plans.module.css delete mode 100644 web/sdk/react/views/plans/pricing-column.tsx rename web/sdk/react/{views-new => views}/preferences/components/preference-row.tsx (95%) rename web/sdk/react/{views-new => views}/preferences/components/preferences-row.module.css (100%) delete mode 100644 web/sdk/react/views/preferences/preferences-page.tsx rename web/sdk/react/{views-new => views}/preferences/preferences-view.module.css (100%) rename web/sdk/react/{views-new => views}/preferences/preferences-view.tsx (95%) delete mode 100644 web/sdk/react/views/preferences/preferences.types.ts delete mode 100644 web/sdk/react/views/profile/profile-page.tsx rename web/sdk/react/{views-new => views}/profile/profile-view.module.css (100%) rename web/sdk/react/{views-new => views}/profile/profile-view.tsx (99%) delete mode 100644 web/sdk/react/views/profile/update-profile.tsx rename web/sdk/react/{views-new => views}/projects/components/add-member-menu.tsx (99%) rename web/sdk/react/{views-new => views}/projects/components/add-project-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/projects/components/delete-project-dialog.tsx (97%) rename web/sdk/react/{views-new => views}/projects/components/edit-project-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/projects/components/member-columns.module.css (100%) rename web/sdk/react/{views-new => views}/projects/components/member-columns.tsx (99%) rename web/sdk/react/{views-new => views}/projects/components/members-cell.module.css (100%) rename web/sdk/react/{views-new => views}/projects/components/members-cell.tsx (97%) rename web/sdk/react/{views-new => views}/projects/components/project-columns.module.css (100%) rename web/sdk/react/{views-new => views}/projects/components/project-columns.tsx (98%) rename web/sdk/react/{views-new => views}/projects/components/remove-member-dialog.tsx (97%) rename web/sdk/react/{views-new => views}/projects/components/update-role-dialog.tsx (99%) delete mode 100644 web/sdk/react/views/projects/details/delete-project-dialog.tsx delete mode 100644 web/sdk/react/views/projects/details/index.ts delete mode 100644 web/sdk/react/views/projects/details/project-detail-page.tsx delete mode 100644 web/sdk/react/views/projects/details/project-detail.module.css delete mode 100644 web/sdk/react/views/projects/details/project-general.tsx delete mode 100644 web/sdk/react/views/projects/details/project-member-columns.tsx delete mode 100644 web/sdk/react/views/projects/details/project-members.module.css delete mode 100644 web/sdk/react/views/projects/details/project-members.tsx delete mode 100644 web/sdk/react/views/projects/details/remove-project-member-dialog.tsx delete mode 100644 web/sdk/react/views/projects/list/add-project-dialog.tsx delete mode 100644 web/sdk/react/views/projects/list/index.ts delete mode 100644 web/sdk/react/views/projects/list/projects-columns.tsx delete mode 100644 web/sdk/react/views/projects/list/projects-list-page.tsx delete mode 100644 web/sdk/react/views/projects/list/projects.module.css rename web/sdk/react/{views-new => views}/projects/project-details-view.module.css (100%) rename web/sdk/react/{views-new => views}/projects/project-details-view.tsx (99%) rename web/sdk/react/{views-new => views}/projects/projects-view.module.css (100%) rename web/sdk/react/{views-new => views}/projects/projects-view.tsx (99%) rename web/sdk/react/{views-new => views}/security/components/add-domain-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/security/components/delete-domain-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/security/components/verify-domain-dialog.tsx (99%) delete mode 100644 web/sdk/react/views/security/security-page.tsx delete mode 100644 web/sdk/react/views/security/security-types.ts rename web/sdk/react/{views-new => views}/security/security-view.module.css (100%) rename web/sdk/react/{views-new => views}/security/security-view.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/add-service-account-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/add-token-form.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/delete-service-account-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/manage-project-access-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/revoke-token-dialog.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/components/service-account-columns.module.css (100%) rename web/sdk/react/{views-new => views}/service-accounts/components/service-account-columns.tsx (98%) rename web/sdk/react/{views-new => views}/service-accounts/hooks/useServiceUserTokens.ts (100%) rename web/sdk/react/{views-new => views}/service-accounts/index.ts (100%) rename web/sdk/react/{views-new => views}/service-accounts/service-account-details-view.module.css (100%) rename web/sdk/react/{views-new => views}/service-accounts/service-account-details-view.tsx (99%) rename web/sdk/react/{views-new => views}/service-accounts/service-accounts-view.module.css (100%) rename web/sdk/react/{views-new => views}/service-accounts/service-accounts-view.tsx (99%) rename web/sdk/react/{views-new => views}/sessions/components/revoke-session-confirm-dialog.tsx (96%) rename web/sdk/react/{views-new => views}/sessions/components/revoke-session-dialog.module.css (100%) rename web/sdk/react/{views-new => views}/sessions/components/revoke-session-dialog.tsx (98%) delete mode 100644 web/sdk/react/views/sessions/revoke-session-dialog.tsx delete mode 100644 web/sdk/react/views/sessions/revoke-session-final-confirm.tsx delete mode 100644 web/sdk/react/views/sessions/session-skeleton.tsx delete mode 100644 web/sdk/react/views/sessions/sessions-page.tsx rename web/sdk/react/{views-new => views}/sessions/sessions-view.module.css (100%) rename web/sdk/react/{views-new => views}/sessions/sessions-view.tsx (96%) delete mode 100644 web/sdk/react/views/sessions/sessions.module.css rename web/sdk/react/{views-new => views}/teams/components/add-member-menu.tsx (98%) rename web/sdk/react/{views-new => views}/teams/components/add-team-dialog.tsx (97%) rename web/sdk/react/{views-new => views}/teams/components/delete-team-dialog.tsx (97%) rename web/sdk/react/{views-new => views}/teams/components/edit-team-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/teams/components/member-columns.module.css (100%) rename web/sdk/react/{views-new => views}/teams/components/member-columns.tsx (99%) rename web/sdk/react/{views-new => views}/teams/components/remove-member-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/teams/components/team-columns.module.css (100%) rename web/sdk/react/{views-new => views}/teams/components/team-columns.tsx (98%) delete mode 100644 web/sdk/react/views/teams/details/delete-team-dialog.tsx delete mode 100644 web/sdk/react/views/teams/details/index.ts delete mode 100644 web/sdk/react/views/teams/details/invite-team-member-dialog.tsx delete mode 100644 web/sdk/react/views/teams/details/team-detail-page.tsx delete mode 100644 web/sdk/react/views/teams/details/team-detail.module.css delete mode 100644 web/sdk/react/views/teams/details/team-general.tsx delete mode 100644 web/sdk/react/views/teams/details/team-member-columns.tsx delete mode 100644 web/sdk/react/views/teams/details/team-members.module.css delete mode 100644 web/sdk/react/views/teams/details/team-members.tsx delete mode 100644 web/sdk/react/views/teams/list/add-team-dialog.tsx delete mode 100644 web/sdk/react/views/teams/list/index.ts delete mode 100644 web/sdk/react/views/teams/list/teams-columns.tsx delete mode 100644 web/sdk/react/views/teams/list/teams-list-page.tsx delete mode 100644 web/sdk/react/views/teams/list/teams.module.css rename web/sdk/react/{views-new => views}/teams/team-details-view.module.css (100%) rename web/sdk/react/{views-new => views}/teams/team-details-view.tsx (99%) rename web/sdk/react/{views-new => views}/teams/teams-view.module.css (100%) rename web/sdk/react/{views-new => views}/teams/teams-view.tsx (99%) delete mode 100644 web/sdk/react/views/tokens/add-tokens-dialog.tsx rename web/sdk/react/{views-new => views}/tokens/components/add-tokens-dialog.tsx (98%) rename web/sdk/react/{views-new => views}/tokens/components/columns.tsx (97%) delete mode 100644 web/sdk/react/views/tokens/token.module.css delete mode 100644 web/sdk/react/views/tokens/tokens-page.tsx rename web/sdk/react/{views-new => views}/tokens/tokens-view.module.css (100%) rename web/sdk/react/{views-new => views}/tokens/tokens-view.tsx (98%) delete mode 100644 web/sdk/react/views/tokens/transactions/columns.tsx delete mode 100644 web/sdk/react/views/tokens/transactions/index.tsx diff --git a/web/apps/admin/package.json b/web/apps/admin/package.json index 8d94ed72c..c14ad262f 100644 --- a/web/apps/admin/package.json +++ b/web/apps/admin/package.json @@ -17,7 +17,7 @@ "@hookform/resolvers": "^3.0.1", "@radix-ui/react-form": "^0.1.8", "@radix-ui/react-icons": "^1.3.0", - "@raystack/apsara": "1.0.0-rc.9", + "@raystack/apsara": "1.0.0-rc.12", "@raystack/frontier": "workspace:^", "@raystack/proton": "0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e", "@stitches/react": "^1.2.8", diff --git a/web/apps/client-demo/package.json b/web/apps/client-demo/package.json index f9ad2b697..6e75128d0 100644 --- a/web/apps/client-demo/package.json +++ b/web/apps/client-demo/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@radix-ui/react-icons": "^1.3.0", - "@raystack/apsara": "1.0.0-rc.9", + "@raystack/apsara": "1.0.0-rc.12", "@raystack/frontier": "workspace:^", "react": "^19.2.1", "react-dom": "^19.2.1", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index b7cf73960..a7c941447 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -55,8 +55,8 @@ importers: specifier: ^1.3.0 version: 1.3.2(react@19.2.4) '@raystack/apsara': - specifier: 1.0.0-rc.9 - version: 1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 1.0.0-rc.12 + version: 1.0.0-rc.12(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@raystack/frontier': specifier: workspace:^ version: link:../../sdk @@ -161,8 +161,8 @@ importers: specifier: ^1.3.0 version: 1.3.2(react@19.2.4) '@raystack/apsara': - specifier: 1.0.0-rc.9 - version: 1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 1.0.0-rc.12 + version: 1.0.0-rc.12(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@raystack/frontier': specifier: workspace:^ version: link:../../sdk @@ -221,9 +221,6 @@ importers: '@hookform/resolvers': specifier: ^3.10.0 version: 3.10.0(react-hook-form@7.71.2(react@19.2.4)) - '@raystack/apsara-v1': - specifier: npm:@raystack/apsara@1.0.0-rc.9 - version: '@raystack/apsara@1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)' '@raystack/proton': specifier: 0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e version: 0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -286,8 +283,8 @@ importers: specifier: ^1.3.2 version: 1.3.2(react@19.2.4) '@raystack/apsara': - specifier: 0.56.6 - version: 0.56.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 1.0.0-rc.12 + version: 1.0.0-rc.12(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@raystack/eslint-config': specifier: workspace:^ version: link:../tools/eslint-config @@ -392,21 +389,6 @@ importers: packages: - '@ariakit/core@0.4.18': - resolution: {integrity: sha512-9urEa+GbZTSyredq3B/3thQjTcSZSUC68XctwCkJNH/xNfKN5O+VThiem2rcJxpsGw8sRUQenhagZi0yB4foyg==} - - '@ariakit/react-core@0.4.22': - resolution: {integrity: sha512-fWzQjMDhMCPGXDJ0/MkYF9vktclwF9XPxKm2fCwYfJMFtAha3ZKXnme2t+IAxguBLtklzW+5xTAEjKV4xn9s7A==} - peerDependencies: - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - - '@ariakit/react@0.4.22': - resolution: {integrity: sha512-NKVBwMIGGfgMr2AoxvmUWmAeE/g6X/pDozR1S0yInF5tyem2DZQm+Td/9mKmZPu5e0x0hbEX1AQrb8SvL4VoBg==} - peerDependencies: - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1502,129 +1484,9 @@ packages: '@protobuf-ts/runtime@2.11.1': resolution: {integrity: sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==} - '@radix-ui/number@1.1.1': - resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} - '@radix-ui/primitive@1.1.3': resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - '@radix-ui/react-accessible-icon@1.1.7': - resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-accordion@1.2.12': - resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-alert-dialog@1.1.15': - resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-aspect-ratio@1.1.7': - resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-avatar@1.1.10': - resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-checkbox@1.3.3': - resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collapsible@1.1.12': - resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-compose-refs@1.1.2': resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: @@ -1634,19 +1496,6 @@ packages: '@types/react': optional: true - '@radix-ui/react-context-menu@2.2.16': - resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-context@1.1.2': resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: @@ -1656,76 +1505,6 @@ packages: '@types/react': optional: true - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-dropdown-menu@2.1.16': - resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-form@0.1.8': resolution: {integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==} peerDependencies: @@ -1739,19 +1518,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-hover-card@1.1.15': - resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-icons@1.3.2': resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} peerDependencies: @@ -1779,8 +1545,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1792,477 +1558,57 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menubar@1.1.16': - resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==} + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: '@types/react': '*' - '@types/react-dom': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-navigation-menu@1.2.14': - resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} peerDependencies: '@types/react': '*' - '@types/react-dom': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-one-time-password-field@0.1.8': - resolution: {integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==} + '@raystack/apsara@1.0.0-rc.12': + resolution: {integrity: sha512-WzL7HD8YMyyhs7zM80V3wm/bxxHTmhNYsi563nPddMtASi51KyyeT0G2CLLTl0mw89XppHp9fjeEM5WsHSOE/g==} + engines: {node: '>=22'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/react': ^19 + react: ^19 + react-dom: ^19 peerDependenciesMeta: '@types/react': optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-password-toggle-field@0.1.3': - resolution: {integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==} + '@raystack/proton@0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e': + resolution: {integrity: sha512-82QvGoJjcp5zGt/QIkdSJEn2iX8vn/g2H4jm8O3QH3YIZuZp0bXFXo+ddD5S49tSUtWiegi7qWJargHgBceLPg==} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@tanstack/react-query': ^5.0.0 peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@tanstack/react-query': optional: true - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@remix-run/router@1.23.2': + resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} + engines: {node: '>=14.0.0'} - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.4': - resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-progress@1.1.7': - resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-radio-group@1.3.8': - resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-scroll-area@1.2.10': - resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-select@2.2.6': - resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-separator@1.1.7': - resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slider@1.3.6': - resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.4': - resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-switch@1.2.6': - resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-tabs@1.1.13': - resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-toast@1.2.15': - resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-toggle-group@1.1.11': - resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-toggle@1.1.10': - resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-toolbar@1.1.11': - resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-is-hydrated@0.1.0': - resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-previous@1.1.1': - resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - - '@raystack/apsara@0.56.6': - resolution: {integrity: sha512-Qt+Nh3CQAaLGtlpo+bNujsgj52PpNVgRG5VySBKEqkTIUZch+R4fOQ5F5zSC8Iv2/4yweuaknTVllNF9o691Eg==} - engines: {node: '>=22'} - peerDependencies: - '@types/react': ^18 || ^19 - react: ^18 || ^19 - react-dom: ^18 || ^19 - peerDependenciesMeta: - '@types/react': - optional: true - - '@raystack/apsara@1.0.0-rc.9': - resolution: {integrity: sha512-RucfY0H0eoVmP594gYWltvmqUicqNPpiH2VPL4EWWhXIsj69NuZXu3i2lvUK7pvgGpRJmkzIg6AdiEhwdxj0pQ==} - engines: {node: '>=22'} - peerDependencies: - '@types/react': ^19 - react: ^19 - react-dom: ^19 - peerDependenciesMeta: - '@types/react': - optional: true - - '@raystack/proton@0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e': - resolution: {integrity: sha512-82QvGoJjcp5zGt/QIkdSJEn2iX8vn/g2H4jm8O3QH3YIZuZp0bXFXo+ddD5S49tSUtWiegi7qWJargHgBceLPg==} - peerDependencies: - '@tanstack/react-query': ^5.0.0 - peerDependenciesMeta: - '@tanstack/react-query': - optional: true - - '@remix-run/router@1.23.2': - resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} - engines: {node: '>=14.0.0'} - - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: + rollup: optional: true '@rollup/rollup-android-arm-eabi@4.59.0': @@ -3100,10 +2446,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -3499,12 +2841,6 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} - cmdk@1.1.1: - resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - react-dom: ^18 || ^19 || ^19.0.0-rc - co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -3523,28 +2859,12 @@ packages: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-convert@3.1.3: - resolution: {integrity: sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==} - engines: {node: '>=14.6'} - color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-name@2.1.0: - resolution: {integrity: sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==} - engines: {node: '>=12.20'} - - color-string@2.1.4: - resolution: {integrity: sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==} - engines: {node: '>=18'} - - color@5.0.3: - resolution: {integrity: sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==} - engines: {node: '>=18'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -3814,9 +3134,6 @@ packages: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4336,10 +3653,6 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -6158,19 +5471,6 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - radix-ui@1.4.3: - resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - ramda@0.29.1: resolution: {integrity: sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==} @@ -6221,26 +5521,6 @@ packages: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - react-router-dom@6.30.3: resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} engines: {node: '>=14.0.0'} @@ -6277,16 +5557,6 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - react-transition-group@4.4.5: resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: @@ -6661,12 +5931,6 @@ packages: react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - sonner@2.0.7: - resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -7261,31 +6525,11 @@ packages: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - use-isomorphic-layout-effect@1.2.1: resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==} peerDependencies: '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true @@ -7590,22 +6834,6 @@ packages: snapshots: - '@ariakit/core@0.4.18': {} - - '@ariakit/react-core@0.4.22(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@ariakit/core': 0.4.18 - '@floating-ui/dom': 1.7.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - use-sync-external-store: 1.6.0(react@19.2.4) - - '@ariakit/react@0.4.22(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@ariakit/react-core': 0.4.22(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -8119,1359 +7347,693 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-arm@0.25.12': - optional: true - - '@esbuild/android-x64@0.17.19': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.25.12': - optional: true - - '@esbuild/darwin-arm64@0.17.19': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.25.12': - optional: true - - '@esbuild/darwin-x64@0.17.19': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.25.12': - optional: true - - '@esbuild/freebsd-arm64@0.17.19': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.25.12': - optional: true - - '@esbuild/freebsd-x64@0.17.19': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.25.12': - optional: true - - '@esbuild/linux-arm64@0.17.19': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.25.12': - optional: true - - '@esbuild/linux-arm@0.17.19': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.25.12': - optional: true - - '@esbuild/linux-ia32@0.17.19': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.25.12': - optional: true - - '@esbuild/linux-loong64@0.17.19': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.25.12': - optional: true - - '@esbuild/linux-mips64el@0.17.19': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.25.12': - optional: true - - '@esbuild/linux-ppc64@0.17.19': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.25.12': - optional: true - - '@esbuild/linux-riscv64@0.17.19': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.25.12': - optional: true - - '@esbuild/linux-s390x@0.17.19': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.25.12': - optional: true - - '@esbuild/linux-x64@0.17.19': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.25.12': - optional: true - - '@esbuild/netbsd-arm64@0.25.12': - optional: true - - '@esbuild/netbsd-x64@0.17.19': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.25.12': - optional: true - - '@esbuild/openbsd-arm64@0.25.12': - optional: true - - '@esbuild/openbsd-x64@0.17.19': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.25.12': - optional: true - - '@esbuild/openharmony-arm64@0.25.12': - optional: true - - '@esbuild/sunos-x64@0.17.19': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.25.12': - optional: true - - '@esbuild/win32-arm64@0.17.19': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.25.12': - optional: true - - '@esbuild/win32-ia32@0.17.19': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.25.12': - optional: true - - '@esbuild/win32-x64@0.17.19': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.25.12': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.14.0 - debug: 4.4.3 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.5 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.1': {} - - '@floating-ui/core@1.7.5': - dependencies: - '@floating-ui/utils': 0.2.11 - - '@floating-ui/dom@1.7.6': - dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/utils': 0.2.11 - - '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@floating-ui/dom': 1.7.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - - '@floating-ui/utils@0.2.11': {} - - '@hookform/resolvers@3.10.0(react-hook-form@7.71.2(react@19.2.4))': - dependencies: - react-hook-form: 7.71.2(react@19.2.4) - - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.5 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} + '@esbuild/android-arm@0.25.12': + optional: true - '@humanwhocodes/object-schema@2.0.3': {} + '@esbuild/android-x64@0.17.19': + optional: true - '@iarna/toml@2.2.5': {} + '@esbuild/android-x64@0.18.20': + optional: true - '@inquirer/external-editor@1.0.3(@types/node@22.19.15)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 22.19.15 + '@esbuild/android-x64@0.25.12': + optional: true - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.2 - resolve-from: 5.0.0 + '@esbuild/darwin-arm64@0.17.19': + optional: true - '@istanbuljs/schema@0.1.3': {} + '@esbuild/darwin-arm64@0.18.20': + optional: true - '@jest/console@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.19.15 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 + '@esbuild/darwin-arm64@0.25.12': + optional: true - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@22.19.15)(typescript@5.9.3))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.15 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.19.15)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@22.19.15)(typescript@5.9.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node + '@esbuild/darwin-x64@0.17.19': + optional: true - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.15 - jest-mock: 29.7.0 + '@esbuild/darwin-x64@0.18.20': + optional: true - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 + '@esbuild/darwin-x64@0.25.12': + optional: true - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color + '@esbuild/freebsd-arm64@0.17.19': + optional: true - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.19.15 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 + '@esbuild/freebsd-arm64@0.18.20': + optional: true - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color + '@esbuild/freebsd-arm64@0.25.12': + optional: true - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 22.19.15 - chalk: 4.1.2 - collect-v8-coverage: 1.0.3 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.2.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color + '@esbuild/freebsd-x64@0.17.19': + optional: true - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.10 + '@esbuild/freebsd-x64@0.18.20': + optional: true - '@jest/source-map@29.6.3': - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - callsites: 3.1.0 - graceful-fs: 4.2.11 + '@esbuild/freebsd-x64@0.25.12': + optional: true - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.3 + '@esbuild/linux-arm64@0.17.19': + optional: true - '@jest/test-sequencer@29.7.0': - dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 + '@esbuild/linux-arm64@0.18.20': + optional: true - '@jest/transform@29.7.0': - dependencies: - '@babel/core': 7.29.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color + '@esbuild/linux-arm64@0.25.12': + optional: true - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.19.15 - '@types/yargs': 17.0.35 - chalk: 4.1.2 + '@esbuild/linux-arm@0.17.19': + optional: true - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + '@esbuild/linux-arm@0.18.20': + optional: true - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@esbuild/linux-arm@0.25.12': + optional: true - '@jridgewell/resolve-uri@3.1.2': {} + '@esbuild/linux-ia32@0.17.19': + optional: true - '@jridgewell/sourcemap-codec@1.5.5': {} + '@esbuild/linux-ia32@0.18.20': + optional: true - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@esbuild/linux-ia32@0.25.12': + optional: true - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@esbuild/linux-loong64@0.17.19': + optional: true - '@ljharb/through@2.3.14': - dependencies: - call-bind: 1.0.8 + '@esbuild/linux-loong64@0.18.20': + optional: true - '@manypkg/find-root@1.1.0': - dependencies: - '@babel/runtime': 7.28.6 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 + '@esbuild/linux-loong64@0.25.12': + optional: true - '@manypkg/get-packages@1.1.3': - dependencies: - '@babel/runtime': 7.28.6 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 + '@esbuild/linux-mips64el@0.17.19': + optional: true - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 + '@esbuild/linux-mips64el@0.18.20': optional: true - '@next/env@13.5.11': {} + '@esbuild/linux-mips64el@0.25.12': + optional: true - '@next/eslint-plugin-next@13.5.11': - dependencies: - glob: 7.1.7 + '@esbuild/linux-ppc64@0.17.19': + optional: true - '@next/swc-darwin-arm64@13.5.9': + '@esbuild/linux-ppc64@0.18.20': optional: true - '@next/swc-darwin-x64@13.5.9': + '@esbuild/linux-ppc64@0.25.12': optional: true - '@next/swc-linux-arm64-gnu@13.5.9': + '@esbuild/linux-riscv64@0.17.19': optional: true - '@next/swc-linux-arm64-musl@13.5.9': + '@esbuild/linux-riscv64@0.18.20': optional: true - '@next/swc-linux-x64-gnu@13.5.9': + '@esbuild/linux-riscv64@0.25.12': optional: true - '@next/swc-linux-x64-musl@13.5.9': + '@esbuild/linux-s390x@0.17.19': optional: true - '@next/swc-win32-arm64-msvc@13.5.9': + '@esbuild/linux-s390x@0.18.20': optional: true - '@next/swc-win32-ia32-msvc@13.5.9': + '@esbuild/linux-s390x@0.25.12': optional: true - '@next/swc-win32-x64-msvc@13.5.9': + '@esbuild/linux-x64@0.17.19': optional: true - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@esbuild/linux-x64@0.18.20': + optional: true - '@nodelib/fs.stat@2.0.5': {} + '@esbuild/linux-x64@0.25.12': + optional: true - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + '@esbuild/netbsd-arm64@0.25.12': + optional: true - '@nolyfill/is-core-module@1.0.39': {} + '@esbuild/netbsd-x64@0.17.19': + optional: true - '@octokit/auth-token@3.0.4': {} + '@esbuild/netbsd-x64@0.18.20': + optional: true - '@octokit/core@4.2.4': - dependencies: - '@octokit/auth-token': 3.0.4 - '@octokit/graphql': 5.0.6 - '@octokit/request': 6.2.8 - '@octokit/request-error': 3.0.3 - '@octokit/types': 9.3.2 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding + '@esbuild/netbsd-x64@0.25.12': + optional: true - '@octokit/endpoint@7.0.6': - dependencies: - '@octokit/types': 9.3.2 - is-plain-object: 5.0.0 - universal-user-agent: 6.0.1 + '@esbuild/openbsd-arm64@0.25.12': + optional: true - '@octokit/graphql@5.0.6': - dependencies: - '@octokit/request': 6.2.8 - '@octokit/types': 9.3.2 - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding + '@esbuild/openbsd-x64@0.17.19': + optional: true - '@octokit/openapi-types@18.1.1': {} + '@esbuild/openbsd-x64@0.18.20': + optional: true - '@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4)': - dependencies: - '@octokit/core': 4.2.4 - '@octokit/tsconfig': 1.0.2 - '@octokit/types': 9.3.2 + '@esbuild/openbsd-x64@0.25.12': + optional: true - '@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4)': - dependencies: - '@octokit/core': 4.2.4 + '@esbuild/openharmony-arm64@0.25.12': + optional: true - '@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4)': - dependencies: - '@octokit/core': 4.2.4 - '@octokit/types': 10.0.0 + '@esbuild/sunos-x64@0.17.19': + optional: true - '@octokit/request-error@3.0.3': - dependencies: - '@octokit/types': 9.3.2 - deprecation: 2.3.1 - once: 1.4.0 + '@esbuild/sunos-x64@0.18.20': + optional: true - '@octokit/request@6.2.8': - dependencies: - '@octokit/endpoint': 7.0.6 - '@octokit/request-error': 3.0.3 - '@octokit/types': 9.3.2 - is-plain-object: 5.0.0 - node-fetch: 2.7.0 - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding + '@esbuild/sunos-x64@0.25.12': + optional: true - '@octokit/rest@19.0.13': - dependencies: - '@octokit/core': 4.2.4 - '@octokit/plugin-paginate-rest': 6.1.2(@octokit/core@4.2.4) - '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.4) - '@octokit/plugin-rest-endpoint-methods': 7.2.3(@octokit/core@4.2.4) - transitivePeerDependencies: - - encoding + '@esbuild/win32-arm64@0.17.19': + optional: true - '@octokit/tsconfig@1.0.2': {} + '@esbuild/win32-arm64@0.18.20': + optional: true - '@octokit/types@10.0.0': - dependencies: - '@octokit/openapi-types': 18.1.1 + '@esbuild/win32-arm64@0.25.12': + optional: true - '@octokit/types@9.3.2': - dependencies: - '@octokit/openapi-types': 18.1.1 + '@esbuild/win32-ia32@0.17.19': + optional: true - '@pnpm/config.env-replace@1.1.0': {} + '@esbuild/win32-ia32@0.18.20': + optional: true - '@pnpm/network.ca-file@1.0.2': - dependencies: - graceful-fs: 4.2.10 + '@esbuild/win32-ia32@0.25.12': + optional: true - '@pnpm/npm-conf@3.0.2': - dependencies: - '@pnpm/config.env-replace': 1.1.0 - '@pnpm/network.ca-file': 1.0.2 - config-chain: 1.1.13 + '@esbuild/win32-x64@0.17.19': + optional: true - '@protobuf-ts/runtime-rpc@2.11.1': - dependencies: - '@protobuf-ts/runtime': 2.11.1 + '@esbuild/win32-x64@0.18.20': + optional: true - '@protobuf-ts/runtime@2.11.1': {} + '@esbuild/win32-x64@0.25.12': + optional: true - '@radix-ui/number@1.1.1': {} + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 - '@radix-ui/primitive@1.1.3': {} + '@eslint-community/regexpp@4.12.2': {} - '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@eslint/eslintrc@2.1.4': dependencies: - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + ajv: 6.14.0 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} - '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/core@1.7.5': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@floating-ui/utils': 0.2.11 - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/dom@1.7.6': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/dom': 1.7.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/utils@0.2.11': {} + + '@hookform/resolvers@3.10.0(react-hook-form@7.71.2(react@19.2.4))': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + react-hook-form: 7.71.2(react@19.2.4) - '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@humanwhocodes/config-array@0.13.0': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iarna/toml@2.2.5': {} - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@inquirer/external-editor@1.0.3(@types/node@22.19.15)': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) + chardet: 2.1.1 + iconv-lite: 0.7.2 optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/node': 22.19.15 - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@istanbuljs/load-nyc-config@1.1.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.2 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/console@29.7.0': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jest/types': 29.6.3 + '@types/node': 22.19.15 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@22.19.15)(typescript@5.9.3))': dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.15 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.19.15)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@22.19.15)(typescript@5.9.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/environment@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.15 + jest-mock: 29.7.0 - '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.4)': + '@jest/expect-utils@29.7.0': dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + jest-get-type: 29.6.3 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/expect@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color - '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.4)': + '@jest/fake-timers@29.7.0': dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.19.15 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/globals@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/reporters@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 22.19.15 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.4)': + '@jest/schemas@29.6.3': dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@sinclair/typebox': 0.27.10 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/source-map@29.6.3': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 - '@radix-ui/react-form@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/test-result@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jest/test-sequencer@29.7.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.15 + '@types/yargs': 17.0.35 + chalk: 4.1.2 - '@radix-ui/react-icons@1.3.2(react@19.2.4)': + '@jridgewell/gen-mapping@0.3.13': dependencies: - react: 19.2.4 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.4)': + '@jridgewell/remapping@2.3.5': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@radix-ui/react-label@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jridgewell/resolve-uri@3.1.2': {} - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jridgewell/sourcemap-codec@1.5.5': {} - '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jridgewell/trace-mapping@0.3.31': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 - '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@jridgewell/trace-mapping@0.3.9': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 - '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@ljharb/through@2.3.14': dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + call-bind: 1.0.8 - '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@manypkg/find-root@1.1.0': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@babel/runtime': 7.28.6 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@manypkg/get-packages@1.1.3': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@babel/runtime': 7.28.6 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/rect': 1.1.1 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@next/env@13.5.11': {} - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@next/eslint-plugin-next@13.5.11': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + glob: 7.1.7 - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@next/swc-darwin-arm64@13.5.9': + optional: true + + '@next/swc-darwin-x64@13.5.9': + optional: true + + '@next/swc-linux-arm64-gnu@13.5.9': + optional: true + + '@next/swc-linux-arm64-musl@13.5.9': + optional: true + + '@next/swc-linux-x64-gnu@13.5.9': + optional: true + + '@next/swc-linux-x64-musl@13.5.9': + optional: true + + '@next/swc-win32-arm64-msvc@13.5.9': + optional: true + + '@next/swc-win32-ia32-msvc@13.5.9': + optional: true + + '@next/swc-win32-x64-msvc@13.5.9': + optional: true + + '@nodelib/fs.scandir@2.1.5': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} - '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@nodelib/fs.walk@1.2.8': dependencies: - '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@octokit/auth-token@3.0.4': {} - '@radix-ui/react-progress@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/core@4.2.4': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/auth-token': 3.0.4 + '@octokit/graphql': 5.0.6 + '@octokit/request': 6.2.8 + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.3.2 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/endpoint@7.0.6': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/types': 9.3.2 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.1 - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/graphql@5.0.6': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/request': 6.2.8 + '@octokit/types': 9.3.2 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/openapi-types@18.1.1': {} - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4)': dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/core': 4.2.4 + '@octokit/tsconfig': 1.0.2 + '@octokit/types': 9.3.2 + + '@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4)': + dependencies: + '@octokit/core': 4.2.4 - '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4)': dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - aria-hidden: 1.2.6 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/core': 4.2.4 + '@octokit/types': 10.0.0 - '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/request-error@3.0.3': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/types': 9.3.2 + deprecation: 2.3.1 + once: 1.4.0 - '@radix-ui/react-slider@1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/request@6.2.8': dependencies: - '@radix-ui/number': 1.1.1 - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/endpoint': 7.0.6 + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.3.2 + is-plain-object: 5.0.0 + node-fetch: 2.7.0 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding - '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)': + '@octokit/rest@19.0.13': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@octokit/core': 4.2.4 + '@octokit/plugin-paginate-rest': 6.1.2(@octokit/core@4.2.4) + '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.4) + '@octokit/plugin-rest-endpoint-methods': 7.2.3(@octokit/core@4.2.4) + transitivePeerDependencies: + - encoding + + '@octokit/tsconfig@1.0.2': {} - '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': + '@octokit/types@10.0.0': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 + '@octokit/openapi-types': 18.1.1 - '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@octokit/types@9.3.2': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@octokit/openapi-types': 18.1.1 + + '@pnpm/config.env-replace@1.1.0': {} - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@pnpm/network.ca-file@1.0.2': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + graceful-fs: 4.2.10 - '@radix-ui/react-toast@1.2.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@pnpm/npm-conf@3.0.2': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 - '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@protobuf-ts/runtime-rpc@2.11.1': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@protobuf-ts/runtime': 2.11.1 + + '@protobuf-ts/runtime@2.11.1': {} - '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.4)': dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-form@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.4)': + '@radix-ui/react-icons@1.3.2(react@19.2.4)': dependencies: react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.4)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.4)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.4)': + '@radix-ui/react-label@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.4)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.14)(react@19.2.4)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)': dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 - use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 @@ -9481,61 +8043,7 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/rect': 1.1.1 - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/rect@1.1.1': {} - - '@raystack/apsara@0.56.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': - dependencies: - '@ariakit/react': 0.4.22(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-icons': 1.3.2(react@19.2.4) - '@tanstack/match-sorter-utils': 8.19.4 - '@tanstack/react-table': 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tanstack/react-virtual': 3.13.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@tanstack/table-core': 8.21.3 - class-variance-authority: 0.7.1 - cmdk: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - color: 5.0.3 - dayjs: 1.11.19 - prism-react-renderer: 2.4.1(react@19.2.4) - radix-ui: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-day-picker: 9.14.0(react@19.2.4) - react-dom: 19.2.4(react@19.2.4) - sonner: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - transitivePeerDependencies: - - '@types/react-dom' - - '@raystack/apsara@1.0.0-rc.9(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@raystack/apsara@1.0.0-rc.12(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@base-ui/react': 1.4.1(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@base-ui/utils': 0.2.8(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10313,10 +8821,6 @@ snapshots: argparse@2.0.1: {} - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -10818,18 +9322,6 @@ snapshots: clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - co@4.6.0: {} code-point-at@1.1.0: {} @@ -10844,25 +9336,10 @@ snapshots: dependencies: color-name: 1.1.4 - color-convert@3.1.3: - dependencies: - color-name: 2.1.0 - color-name@1.1.3: {} color-name@1.1.4: {} - color-name@2.1.0: {} - - color-string@2.1.4: - dependencies: - color-name: 2.1.0 - - color@5.0.3: - dependencies: - color-convert: 3.1.3 - color-string: 2.1.4 - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -11137,8 +9614,6 @@ snapshots: detect-newline@3.1.0: {} - detect-node-es@1.1.0: {} - diff-sequences@29.6.3: {} diff@4.0.4: {} @@ -11902,8 +10377,6 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 - get-nonce@1.0.1: {} - get-package-type@0.1.0: {} get-proto@1.0.1: @@ -14068,69 +12541,6 @@ snapshots: quick-lru@5.1.1: {} - radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-form': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - ramda@0.29.1: {} rc@1.2.8: @@ -14176,25 +12586,6 @@ snapshots: react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.4) - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4) - use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - react-router-dom@6.30.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@remix-run/router': 1.23.2 @@ -14238,14 +12629,6 @@ snapshots: - '@types/react' - supports-color - react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - get-nonce: 1.0.1 - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - react-transition-group@4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@babel/runtime': 7.28.6 @@ -14697,11 +13080,6 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - sonner@2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - source-map-js@1.2.1: {} source-map-support@0.5.13: @@ -15327,27 +13705,12 @@ snapshots: dependencies: prepend-http: 2.0.0 - use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 optionalDependencies: '@types/react': 19.2.14 - use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): - dependencies: - detect-node-es: 1.1.0 - react: 19.2.4 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - use-sync-external-store@1.6.0(react@19.2.4): dependencies: react: 19.2.4 diff --git a/web/sdk/admin/components/AssignRole.tsx b/web/sdk/admin/components/AssignRole.tsx index 2ad4566e5..dcbd288f1 100644 --- a/web/sdk/admin/components/AssignRole.tsx +++ b/web/sdk/admin/components/AssignRole.tsx @@ -6,7 +6,7 @@ import { Radio, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import type { SearchOrganizationUsersResponse_OrganizationUser, Role, diff --git a/web/sdk/admin/components/CustomField.tsx b/web/sdk/admin/components/CustomField.tsx index c3477d8c0..deaa40bbf 100644 --- a/web/sdk/admin/components/CustomField.tsx +++ b/web/sdk/admin/components/CustomField.tsx @@ -5,7 +5,7 @@ import { FormLabel, FormMessage, } from "@radix-ui/react-form"; -import { Flex, Select, Switch, Text, TextArea, Input } from "@raystack/apsara-v1"; +import { Flex, Select, Switch, Text, TextArea, Input } from "@raystack/apsara"; import React, { CSSProperties } from "react"; import { Control, Controller, UseFormRegister } from "react-hook-form"; diff --git a/web/sdk/admin/components/PageHeader.tsx b/web/sdk/admin/components/PageHeader.tsx index 4bf879c50..c6e2be6d9 100644 --- a/web/sdk/admin/components/PageHeader.tsx +++ b/web/sdk/admin/components/PageHeader.tsx @@ -1,5 +1,5 @@ import type { CSSProperties, PropsWithChildren, ReactNode } from "react"; -import { Flex, Text } from "@raystack/apsara-v1"; +import { Flex, Text } from "@raystack/apsara"; import styles from "./page-header.module.css"; export type PageHeaderTypes = { diff --git a/web/sdk/admin/components/SheetFooter.tsx b/web/sdk/admin/components/SheetFooter.tsx index 818100ebc..1e59932bb 100644 --- a/web/sdk/admin/components/SheetFooter.tsx +++ b/web/sdk/admin/components/SheetFooter.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Flex } from "@raystack/apsara-v1"; +import { Flex } from "@raystack/apsara"; type SheetFooterProps = { children?: React.ReactNode; diff --git a/web/sdk/admin/components/SheetHeader.tsx b/web/sdk/admin/components/SheetHeader.tsx index 8a8006f8f..88c81bfe0 100644 --- a/web/sdk/admin/components/SheetHeader.tsx +++ b/web/sdk/admin/components/SheetHeader.tsx @@ -1,6 +1,6 @@ import type { CSSProperties } from "react"; import { Cross1Icon } from "@radix-ui/react-icons"; -import { Flex, Text } from "@raystack/apsara-v1"; +import { Flex, Text } from "@raystack/apsara"; type SheetHeaderProps = { title: string; diff --git a/web/sdk/admin/views/admins/columns.tsx b/web/sdk/admin/views/admins/columns.tsx index cf51e61a4..5170814c5 100644 --- a/web/sdk/admin/views/admins/columns.tsx +++ b/web/sdk/admin/views/admins/columns.tsx @@ -1,4 +1,4 @@ -import { Button, type DataTableColumnDef } from "@raystack/apsara-v1"; +import { Button, type DataTableColumnDef } from "@raystack/apsara"; import type { ServiceUser, User } from "@raystack/proton/frontier"; import { TerminologyEntity } from "../../hooks/useTerminology"; import styles from "./admins.module.css"; diff --git a/web/sdk/admin/views/admins/index.tsx b/web/sdk/admin/views/admins/index.tsx index a00431fa6..aac806354 100644 --- a/web/sdk/admin/views/admins/index.tsx +++ b/web/sdk/admin/views/admins/index.tsx @@ -1,4 +1,4 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; import type { ReactNode } from "react"; import { getColumns } from "./columns"; import styles from "./admins.module.css"; diff --git a/web/sdk/admin/views/audit-logs/actor-cell.tsx b/web/sdk/admin/views/audit-logs/actor-cell.tsx index 65c1368b1..f802b2953 100644 --- a/web/sdk/admin/views/audit-logs/actor-cell.tsx +++ b/web/sdk/admin/views/audit-logs/actor-cell.tsx @@ -1,4 +1,4 @@ -import { Avatar, Flex, getAvatarColor, Text } from "@raystack/apsara-v1"; +import { Avatar, Flex, getAvatarColor, Text } from "@raystack/apsara"; import { AuditRecordActor } from "@raystack/proton/frontier"; import { ACTOR_TYPES, getAuditLogActorName } from "./util"; import systemIcon from "../../assets/images/system.jpg"; diff --git a/web/sdk/admin/views/audit-logs/columns.tsx b/web/sdk/admin/views/audit-logs/columns.tsx index a792623c1..600d82c51 100644 --- a/web/sdk/admin/views/audit-logs/columns.tsx +++ b/web/sdk/admin/views/audit-logs/columns.tsx @@ -1,4 +1,4 @@ -import { Badge, DataTableColumnDef, Flex, Text } from "@raystack/apsara-v1"; +import { Badge, DataTableColumnDef, Flex, Text } from "@raystack/apsara"; import dayjs from "dayjs"; import styles from "./audit-logs.module.css"; import { diff --git a/web/sdk/admin/views/audit-logs/index.tsx b/web/sdk/admin/views/audit-logs/index.tsx index 650849651..bed2be3a5 100644 --- a/web/sdk/admin/views/audit-logs/index.tsx +++ b/web/sdk/admin/views/audit-logs/index.tsx @@ -4,8 +4,8 @@ import { type DataTableSort, EmptyState, Flex, -} from "@raystack/apsara-v1"; -import { useDebouncedState } from "@raystack/apsara-v1/hooks"; +} from "@raystack/apsara"; +import { useDebouncedState } from "@raystack/apsara/hooks"; import { useCallback, useMemo, useState } from "react"; import Navbar from "./navbar"; import styles from "./audit-logs.module.css"; diff --git a/web/sdk/admin/views/audit-logs/navbar.tsx b/web/sdk/admin/views/audit-logs/navbar.tsx index 3844df8ff..3b824f45c 100644 --- a/web/sdk/admin/views/audit-logs/navbar.tsx +++ b/web/sdk/admin/views/audit-logs/navbar.tsx @@ -1,4 +1,4 @@ -import { DataTable, Flex, Text, IconButton, Spinner } from "@raystack/apsara-v1"; +import { DataTable, Flex, Text, IconButton, Spinner } from "@raystack/apsara"; import { CpuChipIcon } from "../../assets/icons/CpuChipIcon"; import styles from "./audit-logs.module.css"; import { DownloadIcon, MagnifyingGlassIcon } from "@radix-ui/react-icons"; diff --git a/web/sdk/admin/views/audit-logs/sidepanel-details.tsx b/web/sdk/admin/views/audit-logs/sidepanel-details.tsx index 488b7721d..2f6fe46d5 100644 --- a/web/sdk/admin/views/audit-logs/sidepanel-details.tsx +++ b/web/sdk/admin/views/audit-logs/sidepanel-details.tsx @@ -1,11 +1,11 @@ -import { Flex, IconButton, SidePanel } from "@raystack/apsara-v1"; +import { Flex, IconButton, SidePanel } from "@raystack/apsara"; import { Cross2Icon, DesktopIcon, GlobeIcon, TransformIcon, } from "@radix-ui/react-icons"; -import { List } from "@raystack/apsara-v1"; +import { List } from "@raystack/apsara"; import styles from "./audit-logs.module.css"; import { AuditRecord } from "@raystack/proton/frontier"; import { ACTOR_TYPES } from "./util"; diff --git a/web/sdk/admin/views/audit-logs/sidepanel-list-id.tsx b/web/sdk/admin/views/audit-logs/sidepanel-list-id.tsx index 724f2bc82..d2641ff25 100644 --- a/web/sdk/admin/views/audit-logs/sidepanel-list-id.tsx +++ b/web/sdk/admin/views/audit-logs/sidepanel-list-id.tsx @@ -1,4 +1,4 @@ -import { CopyButton, Flex, List, Text, Tooltip } from "@raystack/apsara-v1"; +import { CopyButton, Flex, List, Text, Tooltip } from "@raystack/apsara"; import styles from "./audit-logs.module.css"; export default function SidepanelListId({ id = "-" }: { id?: string }) { diff --git a/web/sdk/admin/views/audit-logs/sidepanel-list-link.tsx b/web/sdk/admin/views/audit-logs/sidepanel-list-link.tsx index 13217c687..5b491e785 100644 --- a/web/sdk/admin/views/audit-logs/sidepanel-list-link.tsx +++ b/web/sdk/admin/views/audit-logs/sidepanel-list-link.tsx @@ -1,4 +1,4 @@ -import { Button, List } from "@raystack/apsara-v1"; +import { Button, List } from "@raystack/apsara"; import { ReactNode } from "react"; import styles from "./audit-logs.module.css"; diff --git a/web/sdk/admin/views/audit-logs/sidepanel-log-dialog.tsx b/web/sdk/admin/views/audit-logs/sidepanel-log-dialog.tsx index 55951a042..127aacfe6 100644 --- a/web/sdk/admin/views/audit-logs/sidepanel-log-dialog.tsx +++ b/web/sdk/admin/views/audit-logs/sidepanel-log-dialog.tsx @@ -1,4 +1,4 @@ -import { Dialog, IconButton, CodeBlock } from "@raystack/apsara-v1"; +import { Dialog, IconButton, CodeBlock } from "@raystack/apsara"; import styles from "./audit-logs.module.css"; import { AuditRecord } from "@raystack/proton/frontier"; import { auditLogToJson } from "./util"; diff --git a/web/sdk/admin/views/invoices/columns.tsx b/web/sdk/admin/views/invoices/columns.tsx index bacfe2737..9c6459e5e 100644 --- a/web/sdk/admin/views/invoices/columns.tsx +++ b/web/sdk/admin/views/invoices/columns.tsx @@ -1,4 +1,4 @@ -import { Amount, type DataTableColumnDef, Link, Text } from "@raystack/apsara-v1"; +import { Amount, type DataTableColumnDef, Link, Text } from "@raystack/apsara"; import dayjs from "dayjs"; import type { SearchInvoicesResponse_Invoice } from "@raystack/proton/frontier"; import { diff --git a/web/sdk/admin/views/invoices/index.tsx b/web/sdk/admin/views/invoices/index.tsx index 8c885bee6..e6ac9797b 100644 --- a/web/sdk/admin/views/invoices/index.tsx +++ b/web/sdk/admin/views/invoices/index.tsx @@ -4,7 +4,7 @@ import { type DataTableSort, EmptyState, Flex, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { useState } from "react"; import { PageTitle } from "../../components/PageTitle"; import { InvoicesNavabar } from "./navbar"; diff --git a/web/sdk/admin/views/invoices/navbar.tsx b/web/sdk/admin/views/invoices/navbar.tsx index 74a017809..a965cac13 100644 --- a/web/sdk/admin/views/invoices/navbar.tsx +++ b/web/sdk/admin/views/invoices/navbar.tsx @@ -1,4 +1,4 @@ -import { DataTable, Flex, IconButton, Text } from "@raystack/apsara-v1"; +import { DataTable, Flex, IconButton, Text } from "@raystack/apsara"; import styles from "./invoices.module.css"; import { InvoicesIcon } from "../../assets/icons/InvoicesIcon"; import { FocusEvent, useState } from "react"; diff --git a/web/sdk/admin/views/organizations/details/apis/columns.tsx b/web/sdk/admin/views/organizations/details/apis/columns.tsx index 36858357d..402ba34e8 100644 --- a/web/sdk/admin/views/organizations/details/apis/columns.tsx +++ b/web/sdk/admin/views/organizations/details/apis/columns.tsx @@ -1,4 +1,4 @@ -import { Text, type DataTableColumnDef } from "@raystack/apsara-v1"; +import { Text, type DataTableColumnDef } from "@raystack/apsara"; import dayjs from "dayjs"; import { NULL_DATE } from "../../../../utils/constants"; import styles from "./apis.module.css"; diff --git a/web/sdk/admin/views/organizations/details/apis/details-dialog.tsx b/web/sdk/admin/views/organizations/details/apis/details-dialog.tsx index a8b2f2ccd..93f7d583f 100644 --- a/web/sdk/admin/views/organizations/details/apis/details-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/apis/details-dialog.tsx @@ -1,4 +1,4 @@ -import { Dialog, Flex, Skeleton, Tabs, Text, toastManager } from "@raystack/apsara-v1"; +import { Dialog, Flex, Skeleton, Tabs, Text, toastManager } from "@raystack/apsara"; import styles from "./apis.module.css"; import { useCallback, useEffect, useMemo } from "react"; import dayjs from "dayjs"; diff --git a/web/sdk/admin/views/organizations/details/apis/index.tsx b/web/sdk/admin/views/organizations/details/apis/index.tsx index 0c68a97c5..55c0ff414 100644 --- a/web/sdk/admin/views/organizations/details/apis/index.tsx +++ b/web/sdk/admin/views/organizations/details/apis/index.tsx @@ -1,5 +1,5 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import styles from "./apis.module.css"; import { InfoCircledIcon, ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useCallback, useContext, useEffect, useMemo, useState } from "react"; diff --git a/web/sdk/admin/views/organizations/details/edit/billing.tsx b/web/sdk/admin/views/organizations/details/edit/billing.tsx index fa477fa63..92a280ec4 100644 --- a/web/sdk/admin/views/organizations/details/edit/billing.tsx +++ b/web/sdk/admin/views/organizations/details/edit/billing.tsx @@ -10,7 +10,7 @@ import { Drawer, SidePanel, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./edit.module.css"; import { useCallback, useContext, useEffect, useMemo } from "react"; import { OrganizationContext } from "../contexts/organization-context"; diff --git a/web/sdk/admin/views/organizations/details/edit/kyc.tsx b/web/sdk/admin/views/organizations/details/edit/kyc.tsx index 144d3ec5f..4779ad75c 100644 --- a/web/sdk/admin/views/organizations/details/edit/kyc.tsx +++ b/web/sdk/admin/views/organizations/details/edit/kyc.tsx @@ -11,7 +11,7 @@ import { Switch, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./edit.module.css"; import { z } from "zod"; import { useContext } from "react"; diff --git a/web/sdk/admin/views/organizations/details/edit/organization.tsx b/web/sdk/admin/views/organizations/details/edit/organization.tsx index ab0941fb1..d2acde1ff 100644 --- a/web/sdk/admin/views/organizations/details/edit/organization.tsx +++ b/web/sdk/admin/views/organizations/details/edit/organization.tsx @@ -12,9 +12,9 @@ import { SidePanel, Text, Label, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { Cross1Icon } from "@radix-ui/react-icons"; -import { AvatarUpload } from "../../../../../react/components/avatar-upload"; +import { ImageUpload } from "../../../../../react/components/image-upload"; import { z } from "zod"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -198,7 +198,7 @@ export function EditOrganizationPanel({ open = false, onClose }: { open?: boolea gap={5} style={{ width: "100%" }} > - + Pick a logo for your {t.organization({ case: "lower" })} diff --git a/web/sdk/admin/views/organizations/details/invoices/columns.tsx b/web/sdk/admin/views/organizations/details/invoices/columns.tsx index 3a34cfeb7..c24cf9dda 100644 --- a/web/sdk/admin/views/organizations/details/invoices/columns.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/columns.tsx @@ -1,6 +1,6 @@ import styles from "./invoices.module.css"; import dayjs from "dayjs"; -import { DataTableColumnDef, Link, Amount } from "@raystack/apsara-v1"; +import { DataTableColumnDef, Link, Amount } from "@raystack/apsara"; import type { SearchOrganizationInvoicesResponse_OrganizationInvoice, } from "@raystack/proton/frontier"; diff --git a/web/sdk/admin/views/organizations/details/invoices/index.tsx b/web/sdk/admin/views/organizations/details/invoices/index.tsx index c306c941f..7c2e34d47 100644 --- a/web/sdk/admin/views/organizations/details/invoices/index.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/index.tsx @@ -1,5 +1,5 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import styles from "./invoices.module.css"; import { FileTextIcon, ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useContext, useEffect, useMemo, useState } from "react"; diff --git a/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx b/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx index 0510a6e87..05bb0d0e5 100644 --- a/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx @@ -6,7 +6,7 @@ import { Label, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import React, { useContext } from "react"; import { OrganizationContext } from "../contexts/organization-context"; import { Controller, FormProvider, useForm } from "react-hook-form"; diff --git a/web/sdk/admin/views/organizations/details/layout/index.tsx b/web/sdk/admin/views/organizations/details/layout/index.tsx index 8e074435c..edc4efd3b 100644 --- a/web/sdk/admin/views/organizations/details/layout/index.tsx +++ b/web/sdk/admin/views/organizations/details/layout/index.tsx @@ -1,9 +1,9 @@ import { OrganizationsDetailsNavabar } from "./navbar"; import styles from "./layout.module.css"; -import { EmptyState, Flex, Spinner } from "@raystack/apsara-v1"; +import { EmptyState, Flex, Spinner } from "@raystack/apsara"; import { OrgSidePanel } from "../side-panel/"; import React, { useState } from "react"; -import { OrganizationIcon } from "@raystack/apsara-v1/icons"; +import { OrganizationIcon } from "@raystack/apsara/icons"; import { PageTitle } from "../../../../components/PageTitle"; import { EditKYCPanel } from "../edit/kyc"; import { EditOrganizationPanel } from "../edit/organization"; diff --git a/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx b/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx index f0508a7a2..084a4836d 100644 --- a/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx @@ -7,7 +7,7 @@ import { Text, TextArea, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useContext, useMemo } from 'react'; import styles from './layout.module.css'; import { OrganizationContext } from '../contexts/organization-context'; diff --git a/web/sdk/admin/views/organizations/details/layout/navbar.tsx b/web/sdk/admin/views/organizations/details/layout/navbar.tsx index 7c5e47248..4fb098213 100644 --- a/web/sdk/admin/views/organizations/details/layout/navbar.tsx +++ b/web/sdk/admin/views/organizations/details/layout/navbar.tsx @@ -1,4 +1,4 @@ -import { SidebarIcon, OrganizationIcon } from "@raystack/apsara-v1/icons"; +import { SidebarIcon, OrganizationIcon } from "@raystack/apsara/icons"; import { Flex, @@ -12,7 +12,7 @@ import { getAvatarColor, toastManager, Search -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./layout.module.css"; import { DotsHorizontalIcon } from "@radix-ui/react-icons"; diff --git a/web/sdk/admin/views/organizations/details/members/columns.tsx b/web/sdk/admin/views/organizations/details/members/columns.tsx index 23dfd343b..366bf2a03 100644 --- a/web/sdk/admin/views/organizations/details/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/members/columns.tsx @@ -7,7 +7,7 @@ import { Menu, IconButton, AlertDialog, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import type { SearchOrganizationUsersResponse_OrganizationUser, Role, diff --git a/web/sdk/admin/views/organizations/details/members/index.tsx b/web/sdk/admin/views/organizations/details/members/index.tsx index 26762582a..534b9cc7c 100644 --- a/web/sdk/admin/views/organizations/details/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/members/index.tsx @@ -1,5 +1,5 @@ -import { AlertDialog, DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { AlertDialog, DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import { PageTitle } from "../../../../components/PageTitle"; import styles from "./members.module.css"; import { useContext, useEffect, useMemo, useState } from "react"; diff --git a/web/sdk/admin/views/organizations/details/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/members/remove-member.tsx index 28f02f866..cc3cd1890 100644 --- a/web/sdk/admin/views/organizations/details/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/members/remove-member.tsx @@ -5,7 +5,7 @@ import { } from "@raystack/proton/frontier"; import { create } from "@bufbuild/protobuf"; import { useMutation } from "@connectrpc/connect-query"; -import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara"; import { ConnectError } from "@connectrpc/connect"; import { useTerminology } from "../../../../hooks/useTerminology"; diff --git a/web/sdk/admin/views/organizations/details/members/update-role.tsx b/web/sdk/admin/views/organizations/details/members/update-role.tsx index a2e9d708b..490d0b503 100644 --- a/web/sdk/admin/views/organizations/details/members/update-role.tsx +++ b/web/sdk/admin/views/organizations/details/members/update-role.tsx @@ -13,7 +13,7 @@ import { Button, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { ConnectError } from "@connectrpc/connect"; export type UpdateRolePayload = { diff --git a/web/sdk/admin/views/organizations/details/pat/columns.tsx b/web/sdk/admin/views/organizations/details/pat/columns.tsx index a8d7cbcce..6ae66ee0b 100644 --- a/web/sdk/admin/views/organizations/details/pat/columns.tsx +++ b/web/sdk/admin/views/organizations/details/pat/columns.tsx @@ -4,7 +4,7 @@ import { getAvatarColor, Text, type DataTableColumnDef, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import type { diff --git a/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx b/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx index 092bd0be1..c4d66f0bf 100644 --- a/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx @@ -5,7 +5,7 @@ import { Skeleton, Tabs, Text, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { useQuery } from "@connectrpc/connect-query"; import { FrontierServiceQueries, diff --git a/web/sdk/admin/views/organizations/details/pat/index.tsx b/web/sdk/admin/views/organizations/details/pat/index.tsx index d5a5e4bfd..455ea7b39 100644 --- a/web/sdk/admin/views/organizations/details/pat/index.tsx +++ b/web/sdk/admin/views/organizations/details/pat/index.tsx @@ -1,5 +1,5 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import { LockClosedIcon, ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useCallback, useContext, useEffect, useMemo, useState } from "react"; import { useInfiniteQuery, useQuery } from "@connectrpc/connect-query"; diff --git a/web/sdk/admin/views/organizations/details/projects/columns.tsx b/web/sdk/admin/views/organizations/details/projects/columns.tsx index 4e4958ee3..fe58440c6 100644 --- a/web/sdk/admin/views/organizations/details/projects/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/columns.tsx @@ -5,8 +5,8 @@ import { Flex, Text, Menu, -} from "@raystack/apsara-v1"; -import type { DataTableColumnDef } from "@raystack/apsara-v1"; +} from "@raystack/apsara"; +import type { DataTableColumnDef } from "@raystack/apsara"; import type { SearchOrganizationProjectsResponse_OrganizationProject, User, diff --git a/web/sdk/admin/views/organizations/details/projects/index.tsx b/web/sdk/admin/views/organizations/details/projects/index.tsx index 1b3f87d4d..7f24dc73d 100644 --- a/web/sdk/admin/views/organizations/details/projects/index.tsx +++ b/web/sdk/admin/views/organizations/details/projects/index.tsx @@ -4,7 +4,7 @@ import { Flex, type DataTableQuery, type DataTableSort, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { PageTitle } from "../../../../components/PageTitle"; import styles from "./projects.module.css"; import { useContext, useEffect, useMemo, useState } from "react"; diff --git a/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx b/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx index 8b6ffa0b8..457dd690c 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx @@ -5,7 +5,7 @@ import { Flex, getAvatarColor, Text, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import type React from "react"; import Skeleton from "react-loading-skeleton"; import styles from "./members.module.css"; diff --git a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx index 4ce66b1d5..e653145ae 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx @@ -10,8 +10,8 @@ import { getAvatarColor, Text, AlertDialog, -} from "@raystack/apsara-v1"; -import type { DataTableColumnDef } from "@raystack/apsara-v1"; +} from "@raystack/apsara"; +import type { DataTableColumnDef } from "@raystack/apsara"; import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons"; import { DeleteIcon } from "~/admin/assets/icons/DeleteIcon"; import type { UpdateRolePayload } from "./update-role"; diff --git a/web/sdk/admin/views/organizations/details/projects/members/index.tsx b/web/sdk/admin/views/organizations/details/projects/members/index.tsx index 54ce6a2f7..9ee3a9e91 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/index.tsx @@ -1,5 +1,5 @@ -import { AlertDialog, DataTable, Dialog, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery } from "@raystack/apsara-v1"; +import { AlertDialog, DataTable, Dialog, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery } from "@raystack/apsara"; import { useCallback, useMemo, useState } from "react"; import Skeleton from "react-loading-skeleton"; import { @@ -12,7 +12,7 @@ import { } from "@raystack/proton/frontier"; import { create } from "@bufbuild/protobuf"; import { useQuery, useInfiniteQuery } from "@connectrpc/connect-query"; -import { useDebouncedState } from "@raystack/apsara-v1/hooks"; +import { useDebouncedState } from "@raystack/apsara/hooks"; import styles from "./members.module.css"; import { UsersIcon } from "../../../../../assets/icons/UsersIcon"; import { getColumns } from "./columns"; diff --git a/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx index 6317795f8..9d3464b17 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx @@ -8,7 +8,7 @@ import { create } from "@bufbuild/protobuf"; import { useMutation } from "@connectrpc/connect-query"; import styles from "./members.module.css"; -import { AlertDialog, Button, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { AlertDialog, Button, Flex, Text, toastManager } from "@raystack/apsara"; import { useTerminology } from "../../../../../hooks/useTerminology"; interface RemoveMemberProps { diff --git a/web/sdk/admin/views/organizations/details/projects/members/update-role.tsx b/web/sdk/admin/views/organizations/details/projects/members/update-role.tsx index 719a7bdb6..0aa75a046 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/update-role.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/update-role.tsx @@ -15,7 +15,7 @@ import { Button, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { SCOPES } from "~/admin/utils/constants"; export type UpdateRolePayload = { diff --git a/web/sdk/admin/views/organizations/details/projects/rename-project.tsx b/web/sdk/admin/views/organizations/details/projects/rename-project.tsx index 74adb4381..612288646 100644 --- a/web/sdk/admin/views/organizations/details/projects/rename-project.tsx +++ b/web/sdk/admin/views/organizations/details/projects/rename-project.tsx @@ -1,4 +1,4 @@ -import { Button, Dialog, Field, Flex, Input, toastManager } from "@raystack/apsara-v1"; +import { Button, Dialog, Field, Flex, Input, toastManager } from "@raystack/apsara"; import { FrontierServiceQueries, UpdateProjectRequestSchema, diff --git a/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx b/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx index 9c882c1ab..84e612808 100644 --- a/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx +++ b/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx @@ -1,6 +1,6 @@ import { useCallback, useContext, useMemo, useState } from "react"; import { OrganizationContext } from "../contexts/organization-context"; -import { toastManager } from "@raystack/apsara-v1"; +import { toastManager } from "@raystack/apsara"; import { DEFAULT_ROLES, SCOPES } from "~/admin/utils/constants"; import { useQuery, useMutation } from "@connectrpc/connect-query"; import { FrontierServiceQueries, ListProjectUsersRequestSchema, ListRolesRequestSchema, SetProjectMemberRoleRequestSchema } from "@raystack/proton/frontier"; diff --git a/web/sdk/admin/views/organizations/details/security/block-organization.tsx b/web/sdk/admin/views/organizations/details/security/block-organization.tsx index 19a4dd2f9..58195544f 100644 --- a/web/sdk/admin/views/organizations/details/security/block-organization.tsx +++ b/web/sdk/admin/views/organizations/details/security/block-organization.tsx @@ -1,4 +1,4 @@ -import { AlertDialog, Button, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { AlertDialog, Button, Flex, Text, toastManager } from "@raystack/apsara"; import { useContext, useState } from "react"; import { OrganizationStatus } from "../types"; import { OrganizationContext } from "../contexts/organization-context"; diff --git a/web/sdk/admin/views/organizations/details/security/domains-list.tsx b/web/sdk/admin/views/organizations/details/security/domains-list.tsx index 13e964cd4..f5545b5d3 100644 --- a/web/sdk/admin/views/organizations/details/security/domains-list.tsx +++ b/web/sdk/admin/views/organizations/details/security/domains-list.tsx @@ -5,7 +5,7 @@ import { IconButton, Text, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./security.module.css"; import { CheckCircledIcon, TrashIcon } from "@radix-ui/react-icons"; import Skeleton from "react-loading-skeleton"; diff --git a/web/sdk/admin/views/organizations/details/security/index.tsx b/web/sdk/admin/views/organizations/details/security/index.tsx index f28b08ecd..4c1ca24e0 100644 --- a/web/sdk/admin/views/organizations/details/security/index.tsx +++ b/web/sdk/admin/views/organizations/details/security/index.tsx @@ -5,7 +5,7 @@ import { Text, Tooltip, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from './security.module.css'; import { PlusIcon } from '@radix-ui/react-icons'; diff --git a/web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx b/web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx index 8100a9fe9..73a236e2e 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx @@ -1,4 +1,4 @@ -import { Amount, CopyButton, Flex, Link, List, Text } from "@raystack/apsara-v1"; +import { Amount, CopyButton, Flex, Link, List, Text } from "@raystack/apsara"; import styles from "./side-panel.module.css"; import { convertBillingAddressToString } from "../../../../utils/helper"; import Skeleton from "react-loading-skeleton"; diff --git a/web/sdk/admin/views/organizations/details/side-panel/index.tsx b/web/sdk/admin/views/organizations/details/side-panel/index.tsx index f794c11f5..ef1eb0ba3 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/index.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/index.tsx @@ -1,4 +1,4 @@ -import { Avatar, getAvatarColor, SidePanel } from "@raystack/apsara-v1"; +import { Avatar, getAvatarColor, SidePanel } from "@raystack/apsara"; import { OrganizationDetailsSection } from "./org-details-section"; import { KYCDetailsSection } from "./kyc-section"; import { PlanDetailsSection } from "./plan-details-section"; diff --git a/web/sdk/admin/views/organizations/details/side-panel/kyc-section.tsx b/web/sdk/admin/views/organizations/details/side-panel/kyc-section.tsx index f722c1458..8bd946196 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/kyc-section.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/kyc-section.tsx @@ -1,11 +1,11 @@ -import { Flex, List, Text, Link, Tooltip } from "@raystack/apsara-v1"; +import { Flex, List, Text, Link, Tooltip } from "@raystack/apsara"; import { useContext } from "react"; import styles from "./side-panel.module.css"; import Skeleton from "react-loading-skeleton"; import { CheckCircleFilledIcon, CrossCircleFilledIcon, -} from "@raystack/apsara-v1/icons"; +} from "@raystack/apsara/icons"; import { Link2Icon } from "@radix-ui/react-icons"; import { OrganizationContext } from "../contexts/organization-context"; diff --git a/web/sdk/admin/views/organizations/details/side-panel/org-details-section.tsx b/web/sdk/admin/views/organizations/details/side-panel/org-details-section.tsx index b942a01cf..881c8b458 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/org-details-section.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/org-details-section.tsx @@ -1,5 +1,5 @@ import { CalendarIcon } from "@radix-ui/react-icons"; -import { Flex, List, Text, CopyButton, Tooltip } from "@raystack/apsara-v1"; +import { Flex, List, Text, CopyButton, Tooltip } from "@raystack/apsara"; import styles from "./side-panel.module.css"; import dayjs from "dayjs"; import { useContext } from "react"; diff --git a/web/sdk/admin/views/organizations/details/side-panel/plan-details-section.tsx b/web/sdk/admin/views/organizations/details/side-panel/plan-details-section.tsx index 9699d07b6..7a570f75d 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/plan-details-section.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/plan-details-section.tsx @@ -1,5 +1,5 @@ import { useContext } from "react"; -import { List, Text, Flex } from "@raystack/apsara-v1"; +import { List, Text, Flex } from "@raystack/apsara"; import styles from "./side-panel.module.css"; import { CalendarIcon } from "@radix-ui/react-icons"; import Skeleton from "react-loading-skeleton"; diff --git a/web/sdk/admin/views/organizations/details/side-panel/tokens-details-section.tsx b/web/sdk/admin/views/organizations/details/side-panel/tokens-details-section.tsx index 463c018d4..cc5027e30 100644 --- a/web/sdk/admin/views/organizations/details/side-panel/tokens-details-section.tsx +++ b/web/sdk/admin/views/organizations/details/side-panel/tokens-details-section.tsx @@ -1,5 +1,5 @@ -import { List, Text, Flex } from "@raystack/apsara-v1"; -import { CoinIcon, CoinColoredIcon } from "@raystack/apsara-v1/icons"; +import { List, Text, Flex } from "@raystack/apsara"; +import { CoinIcon, CoinColoredIcon } from "@raystack/apsara/icons"; import styles from "./side-panel.module.css"; import { useContext, useEffect } from "react"; import Skeleton from "react-loading-skeleton"; diff --git a/web/sdk/admin/views/organizations/details/tokens/columns.tsx b/web/sdk/admin/views/organizations/details/tokens/columns.tsx index 4497499d9..38dc02aad 100644 --- a/web/sdk/admin/views/organizations/details/tokens/columns.tsx +++ b/web/sdk/admin/views/organizations/details/tokens/columns.tsx @@ -8,7 +8,7 @@ import { getAvatarColor, Text, Tooltip, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import type { SearchOrganizationTokensResponse_OrganizationToken, } from "@raystack/proton/frontier"; diff --git a/web/sdk/admin/views/organizations/details/tokens/index.tsx b/web/sdk/admin/views/organizations/details/tokens/index.tsx index 4cd4ad1d0..95e35896b 100644 --- a/web/sdk/admin/views/organizations/details/tokens/index.tsx +++ b/web/sdk/admin/views/organizations/details/tokens/index.tsx @@ -1,7 +1,7 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import styles from "./tokens.module.css"; -import { CoinIcon } from "@raystack/apsara-v1/icons"; +import { CoinIcon } from "@raystack/apsara/icons"; import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useContext, useEffect, useMemo, useState } from "react"; import { OrganizationContext } from "../contexts/organization-context"; diff --git a/web/sdk/admin/views/organizations/list/columns.tsx b/web/sdk/admin/views/organizations/list/columns.tsx index 8ce98f291..b3b57abeb 100644 --- a/web/sdk/admin/views/organizations/list/columns.tsx +++ b/web/sdk/admin/views/organizations/list/columns.tsx @@ -5,7 +5,7 @@ import { Flex, getAvatarColor, Text, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import type { SearchOrganizationsResponse_OrganizationResult, Plan, diff --git a/web/sdk/admin/views/organizations/list/create.tsx b/web/sdk/admin/views/organizations/list/create.tsx index 7e1379ae9..f78713d0a 100644 --- a/web/sdk/admin/views/organizations/list/create.tsx +++ b/web/sdk/admin/views/organizations/list/create.tsx @@ -11,7 +11,7 @@ import { Drawer, SidePanel, Text, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { Cross1Icon } from "@radix-ui/react-icons"; import { ImageUpload } from "../../../../react/components/image-upload"; import { z } from "zod"; diff --git a/web/sdk/admin/views/organizations/list/index.tsx b/web/sdk/admin/views/organizations/list/index.tsx index 5379a4b6d..07961ea3e 100644 --- a/web/sdk/admin/views/organizations/list/index.tsx +++ b/web/sdk/admin/views/organizations/list/index.tsx @@ -1,5 +1,5 @@ -import { DataTable, EmptyState, Flex, type DataTableQuery, type DataTableSort } from "@raystack/apsara-v1"; -import { OrganizationIcon } from "@raystack/apsara-v1/icons"; +import { DataTable, EmptyState, Flex, type DataTableQuery, type DataTableSort } from "@raystack/apsara"; +import { OrganizationIcon } from "@raystack/apsara/icons"; import { useEffect, useState } from "react"; import { OrganizationsNavabar } from "./navbar"; import styles from "./list.module.css"; @@ -23,7 +23,7 @@ import { } from "~/utils/connect-pagination"; import { transformDataTableQueryToRQLRequest } from "~/utils/transform-query"; import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; -import { useDebouncedState } from "@raystack/apsara-v1/hooks"; +import { useDebouncedState } from "@raystack/apsara/hooks"; import { useTerminology } from "../../../hooks/useTerminology"; const NoOrganizations = () => { diff --git a/web/sdk/admin/views/organizations/list/navbar.tsx b/web/sdk/admin/views/organizations/list/navbar.tsx index fd63c3ff4..c5122f996 100644 --- a/web/sdk/admin/views/organizations/list/navbar.tsx +++ b/web/sdk/admin/views/organizations/list/navbar.tsx @@ -6,8 +6,8 @@ import { Separator, IconButton, Spinner, -} from "@raystack/apsara-v1"; -import { OrganizationIcon } from "@raystack/apsara-v1/icons"; +} from "@raystack/apsara"; +import { OrganizationIcon } from "@raystack/apsara/icons"; import styles from "./list.module.css"; import { DownloadIcon, diff --git a/web/sdk/admin/views/plans/columns.tsx b/web/sdk/admin/views/plans/columns.tsx index b37606d57..843a32fb2 100644 --- a/web/sdk/admin/views/plans/columns.tsx +++ b/web/sdk/admin/views/plans/columns.tsx @@ -1,4 +1,4 @@ -import { Text, type DataTableColumnDef } from "@raystack/apsara-v1"; +import { Text, type DataTableColumnDef } from "@raystack/apsara"; import type { Plan } from "@raystack/proton/frontier"; import { timestampToDate, type TimeStamp } from "../../utils/connect-timestamp"; import styles from "./plans.module.css"; diff --git a/web/sdk/admin/views/plans/details.tsx b/web/sdk/admin/views/plans/details.tsx index d60a9429e..fab192f4b 100644 --- a/web/sdk/admin/views/plans/details.tsx +++ b/web/sdk/admin/views/plans/details.tsx @@ -1,4 +1,4 @@ -import { Flex, Text, Grid } from "@raystack/apsara-v1"; +import { Flex, Text, Grid } from "@raystack/apsara"; import type { Plan } from "@raystack/proton/frontier"; import { timestampToDate } from "../../utils/connect-timestamp"; diff --git a/web/sdk/admin/views/plans/index.tsx b/web/sdk/admin/views/plans/index.tsx index 5e1e30fa9..cba939599 100644 --- a/web/sdk/admin/views/plans/index.tsx +++ b/web/sdk/admin/views/plans/index.tsx @@ -1,4 +1,4 @@ -import { EmptyState, Flex, DataTable, Drawer } from "@raystack/apsara-v1"; +import { EmptyState, Flex, DataTable, Drawer } from "@raystack/apsara"; import type { ReactNode } from "react"; import type { Plan } from "@raystack/proton/frontier"; import { reduceByKey } from "../../utils/helper"; diff --git a/web/sdk/admin/views/preferences/PreferencesView.tsx b/web/sdk/admin/views/preferences/PreferencesView.tsx index 7be90cb31..3836f8324 100644 --- a/web/sdk/admin/views/preferences/PreferencesView.tsx +++ b/web/sdk/admin/views/preferences/PreferencesView.tsx @@ -1,4 +1,4 @@ -import { Flex, EmptyState } from "@raystack/apsara-v1"; +import { Flex, EmptyState } from "@raystack/apsara"; import type { ReactNode } from "react"; import { createQueryOptions, useTransport } from "@connectrpc/connect-query"; import { diff --git a/web/sdk/admin/views/preferences/columns.tsx b/web/sdk/admin/views/preferences/columns.tsx index c824d7921..c63c37364 100644 --- a/web/sdk/admin/views/preferences/columns.tsx +++ b/web/sdk/admin/views/preferences/columns.tsx @@ -1,4 +1,4 @@ -import { Text, type DataTableColumnDef } from "@raystack/apsara-v1"; +import { Text, type DataTableColumnDef } from "@raystack/apsara"; import { Preference, PreferenceTrait } from "@raystack/proton/frontier"; import styles from "./preferences.module.css"; diff --git a/web/sdk/admin/views/preferences/details.tsx b/web/sdk/admin/views/preferences/details.tsx index d6240b0ee..aee3ebe2e 100644 --- a/web/sdk/admin/views/preferences/details.tsx +++ b/web/sdk/admin/views/preferences/details.tsx @@ -8,7 +8,7 @@ import { Text, Input, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { useCallback, useEffect, useState } from "react"; import Skeleton from "react-loading-skeleton"; import dayjs from "dayjs"; diff --git a/web/sdk/admin/views/preferences/index.tsx b/web/sdk/admin/views/preferences/index.tsx index 45d6b13cf..45cc0b345 100644 --- a/web/sdk/admin/views/preferences/index.tsx +++ b/web/sdk/admin/views/preferences/index.tsx @@ -1,4 +1,4 @@ -import { EmptyState, DataTable, Flex } from "@raystack/apsara-v1"; +import { EmptyState, DataTable, Flex } from "@raystack/apsara"; import type { ReactNode } from "react"; import { Preference, PreferenceTrait } from "@raystack/proton/frontier"; import { PageHeader } from "../../components/PageHeader"; diff --git a/web/sdk/admin/views/products/columns.tsx b/web/sdk/admin/views/products/columns.tsx index ad38fb8d6..7bc7417d6 100644 --- a/web/sdk/admin/views/products/columns.tsx +++ b/web/sdk/admin/views/products/columns.tsx @@ -1,4 +1,4 @@ -import { Flex, Image, Amount, type DataTableColumnDef } from "@raystack/apsara-v1"; +import { Flex, Image, Amount, type DataTableColumnDef } from "@raystack/apsara"; import type { Product } from "@raystack/proton/frontier"; import { timestampToDate, TimeStamp } from "../../utils/connect-timestamp"; import styles from "./products.module.css"; diff --git a/web/sdk/admin/views/products/details.tsx b/web/sdk/admin/views/products/details.tsx index d9e8f398b..4f90ff495 100644 --- a/web/sdk/admin/views/products/details.tsx +++ b/web/sdk/admin/views/products/details.tsx @@ -1,4 +1,4 @@ -import { Flex, Text, Grid, Drawer } from "@raystack/apsara-v1"; +import { Flex, Text, Grid, Drawer } from "@raystack/apsara"; import type { Product } from "@raystack/proton/frontier"; import styles from "./products.module.css"; import { SheetHeader } from "../../components/SheetHeader"; diff --git a/web/sdk/admin/views/products/index.tsx b/web/sdk/admin/views/products/index.tsx index 9585b3302..9fbb73a73 100644 --- a/web/sdk/admin/views/products/index.tsx +++ b/web/sdk/admin/views/products/index.tsx @@ -1,4 +1,4 @@ -import { EmptyState, Flex, DataTable } from "@raystack/apsara-v1"; +import { EmptyState, Flex, DataTable } from "@raystack/apsara"; import type { ReactNode } from "react"; import { useQuery } from "@connectrpc/connect-query"; import { FrontierServiceQueries } from "@raystack/proton/frontier"; diff --git a/web/sdk/admin/views/products/prices/columns.tsx b/web/sdk/admin/views/products/prices/columns.tsx index 3f257ad82..2038e45be 100644 --- a/web/sdk/admin/views/products/prices/columns.tsx +++ b/web/sdk/admin/views/products/prices/columns.tsx @@ -1,6 +1,6 @@ import type { Price as PriceType } from "@raystack/proton/frontier"; -import { Amount } from "@raystack/apsara-v1"; -import type { DataTableColumnDef } from "@raystack/apsara-v1"; +import { Amount } from "@raystack/apsara"; +import type { DataTableColumnDef } from "@raystack/apsara"; import { timestampToDate, TimeStamp } from "../../../utils/connect-timestamp"; import styles from "./prices.module.css"; diff --git a/web/sdk/admin/views/products/prices/index.tsx b/web/sdk/admin/views/products/prices/index.tsx index d629ff7cb..d68371e55 100644 --- a/web/sdk/admin/views/products/prices/index.tsx +++ b/web/sdk/admin/views/products/prices/index.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from "react"; -import { Flex, EmptyState, DataTable } from "@raystack/apsara-v1"; +import { Flex, EmptyState, DataTable } from "@raystack/apsara"; import { useQuery } from "@connectrpc/connect-query"; import { FrontierServiceQueries, type Product } from "@raystack/proton/frontier"; import { PageHeader } from "../../../components/PageHeader"; diff --git a/web/sdk/admin/views/roles/columns.tsx b/web/sdk/admin/views/roles/columns.tsx index 9cbf9047b..bc7ff80df 100644 --- a/web/sdk/admin/views/roles/columns.tsx +++ b/web/sdk/admin/views/roles/columns.tsx @@ -1,4 +1,4 @@ -import { type DataTableColumnDef, Flex } from "@raystack/apsara-v1"; +import { type DataTableColumnDef, Flex } from "@raystack/apsara"; import type { Role } from "@raystack/proton/frontier"; import styles from "./roles.module.css"; export const getColumns: () => DataTableColumnDef[] = () => { diff --git a/web/sdk/admin/views/roles/details.tsx b/web/sdk/admin/views/roles/details.tsx index 9d3bc91c0..3182f0992 100644 --- a/web/sdk/admin/views/roles/details.tsx +++ b/web/sdk/admin/views/roles/details.tsx @@ -1,4 +1,4 @@ -import { Flex, Text, Grid } from "@raystack/apsara-v1"; +import { Flex, Text, Grid } from "@raystack/apsara"; import type { Role } from "@raystack/proton/frontier"; export default function RoleDetails({ role }: { role: Role | null }) { diff --git a/web/sdk/admin/views/roles/index.tsx b/web/sdk/admin/views/roles/index.tsx index 42601e83c..cb2e36279 100644 --- a/web/sdk/admin/views/roles/index.tsx +++ b/web/sdk/admin/views/roles/index.tsx @@ -1,4 +1,4 @@ -import { EmptyState, Flex, DataTable, Drawer } from "@raystack/apsara-v1"; +import { EmptyState, Flex, DataTable, Drawer } from "@raystack/apsara"; import { useCallback, useState, type ReactNode } from "react"; import { reduceByKey } from "../../utils/helper"; diff --git a/web/sdk/admin/views/users/details/layout/layout.tsx b/web/sdk/admin/views/users/details/layout/layout.tsx index 79eee6452..57a955a3c 100644 --- a/web/sdk/admin/views/users/details/layout/layout.tsx +++ b/web/sdk/admin/views/users/details/layout/layout.tsx @@ -1,5 +1,5 @@ import { ReactNode, useState } from "react"; -import { Flex } from "@raystack/apsara-v1"; +import { Flex } from "@raystack/apsara"; import { UserDetailsSidePanel } from "./side-panel"; import styles from "./layout.module.css"; import { UserDetailsNavbar } from "./navbar"; diff --git a/web/sdk/admin/views/users/details/layout/membership-dropdown.tsx b/web/sdk/admin/views/users/details/layout/membership-dropdown.tsx index bfbd22fca..52a5b9320 100644 --- a/web/sdk/admin/views/users/details/layout/membership-dropdown.tsx +++ b/web/sdk/admin/views/users/details/layout/membership-dropdown.tsx @@ -1,4 +1,4 @@ -import { Text, Menu, Skeleton } from "@raystack/apsara-v1"; +import { Text, Menu, Skeleton } from "@raystack/apsara"; import styles from "./side-panel.module.css"; import { useMemo, useState } from "react"; import { diff --git a/web/sdk/admin/views/users/details/layout/navbar.tsx b/web/sdk/admin/views/users/details/layout/navbar.tsx index 914fdbdeb..25538d8b4 100644 --- a/web/sdk/admin/views/users/details/layout/navbar.tsx +++ b/web/sdk/admin/views/users/details/layout/navbar.tsx @@ -5,8 +5,8 @@ import { Flex, IconButton, getAvatarColor, -} from "@raystack/apsara-v1"; -import { SidebarIcon } from "@raystack/apsara-v1/icons"; +} from "@raystack/apsara"; +import { SidebarIcon } from "@raystack/apsara/icons"; import UserIcon from "../../../../assets/icons/UsersIcon"; import styles from "./navbar.module.css"; import { getUserName } from "../../util"; diff --git a/web/sdk/admin/views/users/details/layout/side-panel-details.tsx b/web/sdk/admin/views/users/details/layout/side-panel-details.tsx index 982b4c55a..5c4711b96 100644 --- a/web/sdk/admin/views/users/details/layout/side-panel-details.tsx +++ b/web/sdk/admin/views/users/details/layout/side-panel-details.tsx @@ -1,4 +1,4 @@ -import { Flex, List, Text, CopyButton, Tooltip } from "@raystack/apsara-v1"; +import { Flex, List, Text, CopyButton, Tooltip } from "@raystack/apsara"; import { CalendarIcon } from "@radix-ui/react-icons"; import styles from "./side-panel.module.css"; import { UserState, USER_STATES } from "../../util"; diff --git a/web/sdk/admin/views/users/details/layout/side-panel-membership.tsx b/web/sdk/admin/views/users/details/layout/side-panel-membership.tsx index 36930e4f4..3dc0831c3 100644 --- a/web/sdk/admin/views/users/details/layout/side-panel-membership.tsx +++ b/web/sdk/admin/views/users/details/layout/side-panel-membership.tsx @@ -1,4 +1,4 @@ -import { Flex, List, Text, Avatar } from "@raystack/apsara-v1"; +import { Flex, List, Text, Avatar } from "@raystack/apsara"; import dayjs from "dayjs"; import { CalendarIcon } from "@radix-ui/react-icons"; import Skeleton from "react-loading-skeleton"; diff --git a/web/sdk/admin/views/users/details/layout/side-panel.tsx b/web/sdk/admin/views/users/details/layout/side-panel.tsx index edbc94677..23fe1842a 100644 --- a/web/sdk/admin/views/users/details/layout/side-panel.tsx +++ b/web/sdk/admin/views/users/details/layout/side-panel.tsx @@ -1,4 +1,4 @@ -import { Avatar, getAvatarColor, SidePanel, Text } from "@raystack/apsara-v1"; +import { Avatar, getAvatarColor, SidePanel, Text } from "@raystack/apsara"; import { SidePanelDetails } from "./side-panel-details"; import { SidePanelMembership } from "./side-panel-membership"; import styles from "./side-panel.module.css"; diff --git a/web/sdk/admin/views/users/details/layout/suspend-user.tsx b/web/sdk/admin/views/users/details/layout/suspend-user.tsx index 00c1578a5..5751998d9 100644 --- a/web/sdk/admin/views/users/details/layout/suspend-user.tsx +++ b/web/sdk/admin/views/users/details/layout/suspend-user.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara"; import { useTerminology } from "../../../../hooks/useTerminology"; interface SuspendDropdownProps { diff --git a/web/sdk/admin/views/users/details/security/block-user.tsx b/web/sdk/admin/views/users/details/security/block-user.tsx index e0f48c864..1754e7207 100644 --- a/web/sdk/admin/views/users/details/security/block-user.tsx +++ b/web/sdk/admin/views/users/details/security/block-user.tsx @@ -1,5 +1,5 @@ import { ComponentProps, useCallback, useState } from "react"; -import { AlertDialog, Button, toastManager } from "@raystack/apsara-v1"; +import { AlertDialog, Button, toastManager } from "@raystack/apsara"; import { useUser } from "../user-context"; import { getUserName } from "../../util"; import { diff --git a/web/sdk/admin/views/users/details/security/security.tsx b/web/sdk/admin/views/users/details/security/security.tsx index 8420681c9..57598d028 100644 --- a/web/sdk/admin/views/users/details/security/security.tsx +++ b/web/sdk/admin/views/users/details/security/security.tsx @@ -1,4 +1,4 @@ -import { Flex, Separator, Text } from "@raystack/apsara-v1"; +import { Flex, Separator, Text } from "@raystack/apsara"; import { PageTitle } from "../../../../components/PageTitle"; import { useUser } from "../user-context"; import { BlockUserDialog } from "./block-user"; diff --git a/web/sdk/admin/views/users/details/security/sessions/index.tsx b/web/sdk/admin/views/users/details/security/sessions/index.tsx index 57cc89e5b..abb12817b 100644 --- a/web/sdk/admin/views/users/details/security/sessions/index.tsx +++ b/web/sdk/admin/views/users/details/security/sessions/index.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Flex, Text, Button, toastManager } from "@raystack/apsara-v1"; +import { Flex, Text, Button, toastManager } from "@raystack/apsara"; import { useUser } from "../../user-context"; import { RevokeSessionConfirm } from "./revoke-session-confirm"; import { SessionSkeleton } from "./session-skeleton"; diff --git a/web/sdk/admin/views/users/details/security/sessions/revoke-session-confirm.tsx b/web/sdk/admin/views/users/details/security/sessions/revoke-session-confirm.tsx index 27405c715..67c372145 100644 --- a/web/sdk/admin/views/users/details/security/sessions/revoke-session-confirm.tsx +++ b/web/sdk/admin/views/users/details/security/sessions/revoke-session-confirm.tsx @@ -5,7 +5,7 @@ import { Flex, List, Text -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { RevokeSessionFinalConfirm } from './revoke-session-final-confirm'; import { formatDeviceDisplay } from './index'; import styles from './sessions.module.css'; diff --git a/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx b/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx index 2c995ce06..2f1d2e457 100644 --- a/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx +++ b/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx @@ -4,7 +4,7 @@ import { Dialog, Flex, Text -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import styles from './sessions.module.css'; interface RevokeSessionFinalConfirmProps { diff --git a/web/sdk/admin/views/users/details/security/sessions/session-skeleton.tsx b/web/sdk/admin/views/users/details/security/sessions/session-skeleton.tsx index a9d2de34b..00b607051 100644 --- a/web/sdk/admin/views/users/details/security/sessions/session-skeleton.tsx +++ b/web/sdk/admin/views/users/details/security/sessions/session-skeleton.tsx @@ -1,4 +1,4 @@ -import { Flex, Skeleton } from "@raystack/apsara-v1"; +import { Flex, Skeleton } from "@raystack/apsara"; import styles from "./sessions.module.css"; export const SessionSkeleton = ({ count = 3 }: { count?: number }) => { diff --git a/web/sdk/admin/views/users/details/user-details.tsx b/web/sdk/admin/views/users/details/user-details.tsx index 40c4bc1be..6befd997b 100644 --- a/web/sdk/admin/views/users/details/user-details.tsx +++ b/web/sdk/admin/views/users/details/user-details.tsx @@ -1,4 +1,4 @@ -import { Flex, EmptyState, Spinner } from "@raystack/apsara-v1"; +import { Flex, EmptyState, Spinner } from "@raystack/apsara"; import { PageTitle } from "../../../components/PageTitle"; import UserIcon from "../../../assets/icons/UsersIcon"; import { UserDetailsLayout } from "./layout"; diff --git a/web/sdk/admin/views/users/list/columns.tsx b/web/sdk/admin/views/users/list/columns.tsx index 652a5331e..0083dc7d7 100644 --- a/web/sdk/admin/views/users/list/columns.tsx +++ b/web/sdk/admin/views/users/list/columns.tsx @@ -5,7 +5,7 @@ import { Flex, getAvatarColor, Text, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import dayjs from "dayjs"; import styles from "./list.module.css"; import { getUserName, USER_STATES, UserState } from "../util"; diff --git a/web/sdk/admin/views/users/list/invite-users.tsx b/web/sdk/admin/views/users/list/invite-users.tsx index 9b998f108..52ce166d8 100644 --- a/web/sdk/admin/views/users/list/invite-users.tsx +++ b/web/sdk/admin/views/users/list/invite-users.tsx @@ -8,7 +8,7 @@ import { Text, TextArea, toastManager, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import { PlusIcon } from "@radix-ui/react-icons"; import * as z from "zod"; import { Controller, useForm } from "react-hook-form"; diff --git a/web/sdk/admin/views/users/list/list.tsx b/web/sdk/admin/views/users/list/list.tsx index 67cb40829..7c9fd2d6b 100644 --- a/web/sdk/admin/views/users/list/list.tsx +++ b/web/sdk/admin/views/users/list/list.tsx @@ -1,5 +1,5 @@ -import { DataTable, EmptyState, Flex } from "@raystack/apsara-v1"; -import type { DataTableQuery, DataTableSort } from "@raystack/apsara-v1"; +import { DataTable, EmptyState, Flex } from "@raystack/apsara"; +import type { DataTableQuery, DataTableSort } from "@raystack/apsara"; import Navbar from "./navbar"; import styles from "./list.module.css"; import { getColumns } from "./columns"; @@ -14,7 +14,7 @@ import { } from "~/utils/connect-pagination"; import { transformDataTableQueryToRQLRequest } from "~/utils/transform-query"; import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; -import { useDebouncedState } from "@raystack/apsara-v1/hooks"; +import { useDebouncedState } from "@raystack/apsara/hooks"; import { useTerminology } from "../../../hooks/useTerminology"; const NoUsers = () => { diff --git a/web/sdk/admin/views/users/list/navbar.tsx b/web/sdk/admin/views/users/list/navbar.tsx index 89526eb10..bfd4ff2da 100644 --- a/web/sdk/admin/views/users/list/navbar.tsx +++ b/web/sdk/admin/views/users/list/navbar.tsx @@ -5,7 +5,7 @@ import { Separator, IconButton, Spinner, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./list.module.css"; import { DownloadIcon, MagnifyingGlassIcon } from "@radix-ui/react-icons"; import UserIcon from "../../../assets/icons/UsersIcon"; diff --git a/web/sdk/admin/views/webhooks/webhooks/columns.tsx b/web/sdk/admin/views/webhooks/webhooks/columns.tsx index 8e62552a7..46c45c0a8 100644 --- a/web/sdk/admin/views/webhooks/webhooks/columns.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/columns.tsx @@ -4,7 +4,7 @@ import { Flex, Text, type DataTableColumnDef, -} from "@raystack/apsara-v1"; +} from "@raystack/apsara"; import styles from "./webhooks.module.css"; import { type Webhook } from "@raystack/proton/frontier"; import { diff --git a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx index da55b35eb..fe9056599 100644 --- a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx @@ -1,5 +1,5 @@ import { useCallback } from "react"; -import { Button, Flex, Drawer, toastManager } from "@raystack/apsara-v1"; +import { Button, Flex, Drawer, toastManager } from "@raystack/apsara"; import { SheetHeader } from "../../../../components/SheetHeader"; import { SheetFooter } from "../../../../components/SheetFooter"; import * as z from "zod"; diff --git a/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx b/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx index 85b6e66be..429971070 100644 --- a/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx @@ -1,4 +1,4 @@ -import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara"; import type { useMutation } from "@connectrpc/connect-query"; interface DeleteWebhookDialogProps { diff --git a/web/sdk/admin/views/webhooks/webhooks/index.tsx b/web/sdk/admin/views/webhooks/webhooks/index.tsx index c25687897..ccb543543 100644 --- a/web/sdk/admin/views/webhooks/webhooks/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/index.tsx @@ -1,4 +1,4 @@ -import { Button, Flex, DataTable, EmptyState } from "@raystack/apsara-v1"; +import { Button, Flex, DataTable, EmptyState } from "@raystack/apsara"; import { useCallback, type ReactNode } from "react"; import { getColumns } from "./columns"; import styles from "./webhooks.module.css"; diff --git a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx index 97b49a749..5486676e9 100644 --- a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect } from "react"; -import { Button, Flex, Drawer, toastManager } from "@raystack/apsara-v1"; +import { Button, Flex, Drawer, toastManager } from "@raystack/apsara"; import { SheetHeader } from "../../../../components/SheetHeader"; import { SheetFooter } from "../../../../components/SheetFooter"; import * as z from "zod"; diff --git a/web/sdk/package.json b/web/sdk/package.json index 51882564a..3b2c62282 100644 --- a/web/sdk/package.json +++ b/web/sdk/package.json @@ -45,18 +45,12 @@ "module": "./dist/index.mjs", "require": "./dist/index.js" }, - "./react": { + "./client": { "types": "./react/dist/index.d.ts", "import": "./react/dist/index.mjs", "module": "./react/dist/index.mjs", "require": "./react/dist/index.js" }, - "./client": { - "types": "./react/dist/client.d.ts", - "import": "./react/dist/client.mjs", - "module": "./react/dist/client.mjs", - "require": "./react/dist/client.js" - }, "./hooks": { "types": "./hooks/dist/index.d.ts", "import": "./hooks/dist/index.mjs", @@ -74,7 +68,7 @@ "@jest/globals": "^29.7.0", "@radix-ui/react-form": "^0.1.8", "@radix-ui/react-icons": "^1.3.2", - "@raystack/apsara": "0.56.6", + "@raystack/apsara": "1.0.0-rc.12", "@raystack/eslint-config": "workspace:^", "@raystack/frontier-tsconfig": "workspace:^", "@size-limit/preset-small-lib": "^8.2.6", @@ -107,7 +101,6 @@ "@connectrpc/connect-query": "2.1.1", "@connectrpc/connect-web": "2.1.1", "@hookform/resolvers": "^3.10.0", - "@raystack/apsara-v1": "npm:@raystack/apsara@1.0.0-rc.9", "@raystack/proton": "0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e", "@tanstack/react-query": "^5.90.2", "@tanstack/react-router": "^1.168.3", @@ -124,7 +117,7 @@ "yup": "^1.6.1" }, "peerDependencies": { - "@raystack/apsara": ">=0.30.0", + "@raystack/apsara": ">=1.0.0-rc.0", "@types/react": "^19", "react": "^19", "react-dom": "^19" diff --git a/web/sdk/react/client.ts b/web/sdk/react/client.ts deleted file mode 100644 index a80595bdd..000000000 --- a/web/sdk/react/client.ts +++ /dev/null @@ -1,58 +0,0 @@ -import '@raystack/apsara-v1/style.css'; -import '@raystack/apsara-v1/normalize.css'; - -export { ImageUpload } from './components/image-upload'; -export { ViewContainer } from './components/view-container'; -export { ViewHeader } from './components/view-header'; -export { AuthContainer } from './components/auth-container'; -export { AuthHeader } from './components/auth-header'; - -export { SignInView } from './views-new/auth/sign-in'; -export { SignUpView } from './views-new/auth/sign-up'; -export { MagicLinkView } from './views-new/auth/magic-link'; -export { MagicLinkVerifyView } from './views-new/auth/magic-link-verify'; -export { SubscribeView } from './views-new/auth/subscribe'; -export { UpdatesView } from './views-new/auth/updates'; - -export { GeneralView } from './views-new/general'; -export { PreferencesView, PreferenceRow } from './views-new/preferences'; -export { ProfileView } from './views-new/profile'; -export { SessionsView } from './views-new/sessions'; -export { MembersView } from './views-new/members'; -export { SecurityView } from './views-new/security'; -export { ProjectsView, ProjectDetailsView } from './views-new/projects'; -export { BillingView } from './views-new/billing'; -export { TokensView } from './views-new/tokens'; -export { TeamsView, TeamDetailsView } from './views-new/teams'; -export { - ServiceAccountsView, - ServiceAccountDetailsView -} from './views-new/service-accounts'; -export { PlansView } from './views-new/plans'; -export { PatsView, PATDetailsView } from './views-new/pat'; -export { CreateOrganizationView } from './views-new/create-organization'; - -export { useFrontier } from './contexts/FrontierContext'; -export { FrontierProvider, queryClient } from './contexts/FrontierProvider'; -export { CustomizationProvider } from './contexts/CustomizationContext'; - -export { useTerminology } from './hooks/useTerminology'; -export { useTokens } from './hooks/useTokensV1'; -export { useBillingPermission } from './hooks/useBillingPermission'; -export { useConnectQueryPolling } from './hooks/useConnectQueryPolling'; -export { usePreferences } from './hooks/usePreferences'; - -export type { - FrontierClientOptions, - FrontierClientBillingOptions, - FrontierClientCustomizationOptions -} from '../shared/types'; - -export { PREFERENCE_OPTIONS } from './utils/constants'; - -export { - timestampToDate, - timestampToDayjs, - isNullTimestamp -} from '../utils/timestamp'; -export type { TimeStamp } from '../utils/timestamp'; diff --git a/web/sdk/react/components/Container.tsx b/web/sdk/react/components/Container.tsx deleted file mode 100644 index 1b6cef722..000000000 --- a/web/sdk/react/components/Container.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Flex } from '@raystack/apsara'; -import { cva } from 'class-variance-authority'; -import React, { ComponentPropsWithRef } from 'react'; -// @ts-ignore -import styles from './container.module.css'; - -type ContainerProps = ComponentPropsWithRef<'div'> & { - children?: React.ReactNode; - shadow?: 'none' | 'xs' | 'sm' | 'md' | 'lg'; - radius?: 'none' | 'xs' | 'sm' | 'md' | 'lg'; - className?: string; -}; - -const container = cva(styles.container, { - variants: { - shadow: { - none: '', - xs: styles.shadowxs, - sm: styles.shadowsm, - md: styles.shadowmd, - lg: styles.shadowlg - }, - radius: { - none: '', - xs: styles.radiusxs, - sm: styles.radiussm, - md: styles.radiusmd, - lg: styles.radiuslg - } - }, - defaultVariants: { - shadow: 'none', - radius: 'none' - } -}); - -export const Container = ({ - children, - shadow = 'none', - radius = 'md', - style, - className -}: ContainerProps) => { - return ( - - {children} - - ); -}; diff --git a/web/sdk/react/components/Header.tsx b/web/sdk/react/components/Header.tsx deleted file mode 100644 index 66a3c18e2..000000000 --- a/web/sdk/react/components/Header.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Headline, Flex } from '@raystack/apsara'; -import React, { ComponentPropsWithRef } from 'react'; -import logo from '~/react/assets/logo.png'; - -// @ts-ignore -import styles from './header.module.css'; - -const defaultLogo = ( - // eslint-disable-next-line @next/next/no-img-element - logo -); - -type HeaderProps = ComponentPropsWithRef<'div'> & { - title?: string; - logo?: React.ReactNode; -}; - -export const Header = ({ title, logo }: HeaderProps) => { - return ( - -
{logo ? logo : defaultLogo}
-
- {title} -
-
- ); -}; diff --git a/web/sdk/react/components/Layout/index.tsx b/web/sdk/react/components/Layout/index.tsx deleted file mode 100644 index 8e13ea1a0..000000000 --- a/web/sdk/react/components/Layout/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Flex } from '@raystack/apsara'; -import { PropsWithChildren } from 'react'; -import { PageHeader } from '../common/page-header'; -import sharedStyles from '../organization/styles.module.css'; - -interface LayoutProps { - title: string; - description?: string; -} - -export function Layout({ title, description, children }: PropsWithChildren) { - return ( - - - - - - - {children} - - - - ); -} diff --git a/web/sdk/react/components/Layout/layout.module.css b/web/sdk/react/components/Layout/layout.module.css deleted file mode 100644 index 2a629fc8c..000000000 --- a/web/sdk/react/components/Layout/layout.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.header { - padding: var(--rs-space-5) var(--rs-space-11); - border-bottom: 1px solid var(--rs-color-border-base-primary); - gap: var(--rs-space-3); -} - -.container { - padding: var(--rs-space-9) var(--rs-space-11); - overflow: scroll; -} diff --git a/web/sdk/react/components/auth-container/auth-container.tsx b/web/sdk/react/components/auth-container/auth-container.tsx index 81c3e0994..2de64bc14 100644 --- a/web/sdk/react/components/auth-container/auth-container.tsx +++ b/web/sdk/react/components/auth-container/auth-container.tsx @@ -1,5 +1,5 @@ import { ComponentPropsWithRef, ReactNode } from 'react'; -import { Flex } from '@raystack/apsara-v1'; +import { Flex } from '@raystack/apsara'; import { cx } from 'class-variance-authority'; import styles from './auth-container.module.css'; diff --git a/web/sdk/react/components/auth-header/auth-header.tsx b/web/sdk/react/components/auth-header/auth-header.tsx index 2cb8f62b2..9c4ce96dc 100644 --- a/web/sdk/react/components/auth-header/auth-header.tsx +++ b/web/sdk/react/components/auth-header/auth-header.tsx @@ -1,5 +1,5 @@ import { ComponentPropsWithRef, ReactNode } from 'react'; -import { Flex, Headline } from '@raystack/apsara-v1'; +import { Flex, Headline } from '@raystack/apsara'; import logo from '~/react/assets/logo.png'; import styles from './auth-header.module.css'; diff --git a/web/sdk/react/components/auth-oidc-button/auth-oidc-button.tsx b/web/sdk/react/components/auth-oidc-button/auth-oidc-button.tsx index 91be9f26a..c04819810 100644 --- a/web/sdk/react/components/auth-oidc-button/auth-oidc-button.tsx +++ b/web/sdk/react/components/auth-oidc-button/auth-oidc-button.tsx @@ -1,4 +1,4 @@ -import { Button, Text } from '@raystack/apsara-v1'; +import { Button, Text } from '@raystack/apsara'; import { HTMLProps } from 'react'; import GoogleLogo from '~/react/assets/logos/google-logo.svg'; import { capitalize } from '~/utils'; diff --git a/web/sdk/react/components/avatar-upload/avatar-upload.module.css b/web/sdk/react/components/avatar-upload/avatar-upload.module.css deleted file mode 100644 index be8f18a85..000000000 --- a/web/sdk/react/components/avatar-upload/avatar-upload.module.css +++ /dev/null @@ -1,60 +0,0 @@ -.container { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: var(--rs-space-5); - align-self: stretch; -} - -.uploadIconWrapper { - display: flex; - width: 80px; - height: 80px; - box-sizing: border-box; - gap: var(--rs-space-5); - justify-content: center; - align-items: center; - border-radius: var(--rs-radius-2, 4px); - border: 1px dashed var(--rs-color-border-accent-primary); - color: var(--rs-color-foreground-accent-primary); - cursor: pointer; -} - -.uploadIconWrapper > svg { - width: 48px; - height: 48px; -} - -.inputFileField { - display: none; -} - -.overlay { - background-color: rgba(104, 112, 118, 0.5); -} - -.cropModal { - padding: 0; - max-width: 600px; - max-height: fit-content; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.reactCrop:focus { - border-color: transparent; -} - -.modalContentBox { - padding: 16px 32px; - max-height: '280px'; - height: 100%; -} - -.previewImg { - max-height: 248px !important; /* modalContentBox's max-height - 2x modalContentBox'padding */ - object-fit: contain; -} diff --git a/web/sdk/react/components/avatar-upload/index.tsx b/web/sdk/react/components/avatar-upload/index.tsx deleted file mode 100644 index 8ad5170d2..000000000 --- a/web/sdk/react/components/avatar-upload/index.tsx +++ /dev/null @@ -1,250 +0,0 @@ -import ReactCrop, { - type Crop, - type PixelCrop, - type PercentCrop, - centerCrop, - makeAspectCrop -} from 'react-image-crop'; -import { UploadIcon } from '@radix-ui/react-icons'; -import React, { useRef, useState } from 'react'; -import { Button, Avatar, Image, Text, Dialog, Flex } from '@raystack/apsara'; - -import cross from '~/react/assets/cross.svg'; -import 'react-image-crop/dist/ReactCrop.css'; -import styles from './avatar-upload.module.css'; - -interface CropModalProps { - imgSrc?: string; - onClose: () => void; - // eslint-disable-next-line no-unused-vars - onSave: (data: string) => void; -} - -function CropModal({ onClose, imgSrc, onSave }: CropModalProps) { - const [crop, setCrop] = useState(); - - const imgRef = useRef(null); - - async function handleSave() { - const image = imgRef.current; - if (!image) { - throw new Error('No Image Selected'); - } - - const canvas = document.createElement('canvas'); - const scaleX = image.naturalWidth / image.width; - const scaleY = image.naturalHeight / image.height; - - const height = ((crop?.height || 0) * image.height) / 100; - const width = ((crop?.width || 0) * image.width) / 100; - const x = ((crop?.x || 0) * image.width) / 100; - const y = ((crop?.y || 0) * image.width) / 100; - - const pixelRatio = window.devicePixelRatio; - canvas.width = width * pixelRatio; - canvas.height = height * pixelRatio; - const ctx = canvas.getContext('2d'); - - if (!ctx) { - throw new Error('No 2d context'); - } - - ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); - ctx.imageSmoothingQuality = 'high'; - - ctx.drawImage( - image, - x * scaleX, - y * scaleY, - width * scaleX, - height * scaleY, - 0, - 0, - width, - height - ); - - const base64Image = canvas.toDataURL('image/jpeg'); - onSave(base64Image); - onClose(); - } - - function onImageLoad(e: React.SyntheticEvent) { - const { naturalWidth: width, naturalHeight: height } = e.currentTarget; - const crop = centerCrop( - makeAspectCrop( - { - unit: '%', - width: 100 - }, - 1, - width, - height - ), - width, - height - ); - setCrop(crop); - } - - return ( - - - - - - Crop your photo - - cross - - - - - - {imgSrc ? ( - setCrop(percentCrop)} - aspect={1} - className={styles.reactCrop} - data-test-id="frontier-sdk-image-crop-preview" - > - preview-pic - - ) : null} - - - - - - - - - - - - ); -} - -interface AvatarUploadProps { - subText?: string; - value?: string; - onChange?: (value: string) => void; - disabled?: boolean; - initials?: string; -} - -export const AvatarUpload = React.forwardRef< - React.ElementRef<'div'>, - AvatarUploadProps ->( - ( - { subText, value, onChange = () => {}, initials = '', disabled = false }, - forwardedRef - ) => { - const inputRef = useRef(null); - const [imgSrc, setImgSrc] = useState(''); - const [showCropModal, setShowCropModal] = useState(false); - const [isHover, setIsHover] = useState(false); - - function onUploadIconClick() { - const inputField = inputRef.current; - inputField?.click(); - } - - function onFileChange(e: React.ChangeEvent) { - const files = e.target.files || []; - if (files.length > 0) { - const file = files[0]; - const imageUrl = URL.createObjectURL(file); - setImgSrc(imageUrl); - setShowCropModal(true); - e.target.files = null; - } - } - - function onCloseClick() { - setShowCropModal(false); - } - - // disabled && value => show logo without onClick event - // disabled && !value => show avatar with fallback - // !disabled && value => allow user to click logo and update - // !disabled && !value => show upload icon and update - - return ( -
- {disabled ? ( -
- -
- ) : ( -
setIsHover(true)} - onMouseLeave={() => setIsHover(false)} - > - {value && !isHover ? ( - - ) : ( -
- -
- )} -
- )} - - {subText ? {subText} : null} - - {showCropModal ? ( - - ) : null} -
- ); - } -); - -AvatarUpload.displayName = 'AvatarUpload'; diff --git a/web/sdk/react/components/common/page-header/index.tsx b/web/sdk/react/components/common/page-header/index.tsx deleted file mode 100644 index 580308d01..000000000 --- a/web/sdk/react/components/common/page-header/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -'use client'; - -import { Flex, Headline, Text } from '@raystack/apsara'; -import { ReactNode } from 'react'; - -interface PageHeaderProps { - title: string; - description?: string | ReactNode; -} - -/** - * PageHeader - Component for displaying page header with a title and optional description on top of SDK pages. - * - * @param title - The main heading text for the page - * @param description - Optional description text or ReactNode displayed below the title - * - * @example - * - */ -export const PageHeader = ({ title, description }: PageHeaderProps) => { - return ( - - {title} - {description && ( - - {description} - - )} - - ); -}; - diff --git a/web/sdk/react/components/common/upcoming-plan-change-banner/index.tsx b/web/sdk/react/components/common/upcoming-plan-change-banner/index.tsx deleted file mode 100644 index 05613a834..000000000 --- a/web/sdk/react/components/common/upcoming-plan-change-banner/index.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { Button, Skeleton, Text, Flex, toast } from '@raystack/apsara'; -import { - DEFAULT_DATE_FORMAT, - SUBSCRIPTION_STATES -} from '~/react/utils/constants'; -import { Subscription, ChangeSubscriptionRequestSchema } from '@raystack/proton/frontier'; -import styles from './styles.module.css'; -import { InfoCircledIcon } from '@radix-ui/react-icons'; -import dayjs from 'dayjs'; -import { useCallback, useMemo } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation, FrontierServiceQueries } from '~hooks'; -import { create } from '@bufbuild/protobuf'; -import { useQueryClient } from '@tanstack/react-query'; -import { createConnectQueryKey, useTransport } from '@connectrpc/connect-query'; -import { - checkSimilarPlans, - getPlanChangeAction, - getPlanIntervalName, - getPlanNameWithInterval -} from '~/react/utils'; -import { timestampToDayjs } from '~/utils/timestamp'; - -interface ChangeBannerProps { - isLoading?: boolean; - subscription?: Subscription; - isAllowed: boolean; -} - -export function UpcomingPlanChangeBanner({ - isLoading, - subscription, - isAllowed -}: ChangeBannerProps) { - const { - config, - activePlan, - activeOrganization, - basePlan, - allPlans, - isAllPlansLoading - } = useFrontier(); - - const queryClient = useQueryClient(); - const transport = useTransport(); - - const { mutate: cancelUpcomingChange, isPending: isPlanChangeLoading } = useMutation( - FrontierServiceQueries.changeSubscription, - { - onSuccess: async () => { - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listSubscriptions, - transport, - input: { - orgId: activeOrganization?.id ?? '' - }, - cardinality: 'finite' - }) - }); - toast.success(`Success: Your ${activePlan?.title} is resumed`); - }, - onError: (err) => { - console.error(err); - toast.error('Failed to resume plan', { - description: err.message - }); - } - } - ); - - const phases = - subscription?.phases?.filter(phase => - timestampToDayjs(phase.effectiveAt)?.isAfter(dayjs()) - ) || []; - - const nextPhase = phases?.[0]; - - const upcomingPlan = useMemo(() => { - if (nextPhase?.planId && allPlans.length > 0) { - const plan = allPlans.find(p => p.id === nextPhase?.planId); - return plan; - } - }, [nextPhase?.planId, allPlans]); - - const expiryDate = nextPhase?.effectiveAt - ? timestampToDayjs(nextPhase?.effectiveAt)?.format( - config?.dateFormat || DEFAULT_DATE_FORMAT - ) - : ''; - - const newPlanMetadata = upcomingPlan?.metadata as Record; - const activePlanMetadata = activePlan?.metadata as Record; - - const planAction = getPlanChangeAction( - Number(newPlanMetadata?.weightage), - Number(activePlanMetadata?.weightage) - ); - - const showLoader = isLoading || isAllPlansLoading; - - const onPlanChangeCancel = useCallback(() => { - if (subscription?.id) { - cancelUpcomingChange( - create(ChangeSubscriptionRequestSchema, { - id: subscription?.id, - change: { - case: 'phaseChange', - value: { - cancelUpcomingChanges: true - } - } - }) - ); - } - }, [subscription?.id, cancelUpcomingChange]); - - const currentPlanName = getPlanNameWithInterval(activePlan); - const upcomingPlanName = getPlanNameWithInterval(upcomingPlan || basePlan); - - const areSimilarPlans = checkSimilarPlans(activePlan, upcomingPlan); - - const resumePlanTitle = areSimilarPlans - ? getPlanIntervalName(activePlan) - : activePlan?.title; - - const showBanner = - nextPhase?.planId || - (subscription?.state === SUBSCRIPTION_STATES.ACTIVE && - nextPhase?.reason === 'cancel'); - - return showLoader ? ( - - ) : showBanner ? ( - - - - - Your {currentPlanName} will be{' '} - {planAction?.btnDoneLabel.toLowerCase()} to {upcomingPlanName} from{' '} - {expiryDate}. - - - - {isAllowed ? ( - - ) : null} - - - ) : null; -} diff --git a/web/sdk/react/components/common/upcoming-plan-change-banner/styles.module.css b/web/sdk/react/components/common/upcoming-plan-change-banner/styles.module.css deleted file mode 100644 index 98e2569b2..000000000 --- a/web/sdk/react/components/common/upcoming-plan-change-banner/styles.module.css +++ /dev/null @@ -1,15 +0,0 @@ -.changeBannerBox { - padding: var(--rs-space-3); - border-radius: var(--rs-space-2); - border: 0.5px solid var(--rs-color-border-accent-primary); - background: var(--rs-color-background-accent-primary); -} - -.flex1 { - flex: 1; -} - -.currentPlanInfoText { - color: var(--rs-color-foreground-base-primary); - font-weight: 400; -} diff --git a/web/sdk/react/components/container.module.css b/web/sdk/react/components/container.module.css deleted file mode 100644 index de04d9934..000000000 --- a/web/sdk/react/components/container.module.css +++ /dev/null @@ -1,36 +0,0 @@ -.container { - min-width: 220px; - max-width: 480px; - width: 100%; - color: var(--rs-color-foreground-base-primary); -} - -.title { - font-weight: 400; -} - -.shadowxs { - box-shadow: var(--rs-shadow-feather); -} -.shadowsm { - box-shadow: var(--rs-shadow-soft); -} -.shadowmd { - box-shadow: var(--rs-shadow-lifted); -} -.shadowlg { - box-shadow: var(--rs-shadow-floating); -} - -.radiusxs { - border-radius: var(--rs-radius-2); -} -.radiussm { - border-radius: var(--rs-radius-4); -} -.radiusmd { - border-radius: var(--rs-radius-6); -} -.radiuslg { - border-radius: 24px; -} \ No newline at end of file diff --git a/web/sdk/react/components/header.module.css b/web/sdk/react/components/header.module.css deleted file mode 100644 index 35343bf87..000000000 --- a/web/sdk/react/components/header.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.container { - min-width: 220px; - max-width: 100%; - color: var(--rs-color-foreground-base-primary); -} - -.title { - font-weight: 400; -} \ No newline at end of file diff --git a/web/sdk/react/components/image-upload/image-upload.tsx b/web/sdk/react/components/image-upload/image-upload.tsx index 5729a9ca1..737ff0f84 100644 --- a/web/sdk/react/components/image-upload/image-upload.tsx +++ b/web/sdk/react/components/image-upload/image-upload.tsx @@ -16,7 +16,7 @@ import { Flex, IconButton, Text -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import 'react-image-crop/dist/ReactCrop.css'; import styles from './image-upload.module.css'; import { type SyntheticEvent, type ChangeEvent } from 'react'; diff --git a/web/sdk/react/components/index.ts b/web/sdk/react/components/index.ts deleted file mode 100644 index fcb9763d1..000000000 --- a/web/sdk/react/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './onboarding/signin'; diff --git a/web/sdk/react/components/onboarding/magiclink-verify.tsx b/web/sdk/react/components/onboarding/magiclink-verify.tsx deleted file mode 100644 index f97fbcc08..000000000 --- a/web/sdk/react/components/onboarding/magiclink-verify.tsx +++ /dev/null @@ -1,126 +0,0 @@ -'use client'; - -import { Button, Text, Link, Flex, InputField } from '@raystack/apsara'; -import React, { - ComponentPropsWithRef, - useCallback, - useEffect, - useRef, - useState -} from 'react'; -import { Container } from '~/react/components/Container'; -import { Header } from '~/react/components/Header'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation, FrontierServiceQueries } from '~hooks'; - -// @ts-ignore -import styles from './onboarding.module.css'; - -type MagicLinkVerifyProps = ComponentPropsWithRef & { - logo?: React.ReactNode; - title?: string; - redirectURL?: string; -}; - -export const MagicLinkVerify = ({ - logo, - title = 'Check your email', - redirectURL, - ...props -}: MagicLinkVerifyProps) => { - const { config } = useFrontier(); - - const { mutateAsync: authCallback, isPending } = useMutation( - FrontierServiceQueries.authCallback - ); - const [emailParam, setEmailParam] = useState(''); - const [stateParam, setStateParam] = useState(''); - const [otp, setOTP] = useState(''); - const [submitError, setSubmitError] = useState(''); - const isButtonDisabledRef = useRef(true); - - const handleOTPChange = (event: React.ChangeEvent) => { - const { value } = event.target; - isButtonDisabledRef.current = value.length === 0; - if (submitError.length > 0) setSubmitError(''); - setOTP(value); - }; - - useEffect(() => { - const params = new URLSearchParams(window.location.search); - const emailParam = params.get('email'); - const stateParam = params.get('state'); - - emailParam && setEmailParam(emailParam); - stateParam && setStateParam(stateParam); - }, []); - - const OTPVerifyHandler = useCallback( - async (e: React.FormEvent) => { - e.preventDefault(); - try { - await authCallback({ - strategyName: 'mailotp', - code: otp, - state: stateParam - }); - - // @ts-ignore - const destination = - redirectURL ?? window.location.origin; - window.location.replace(destination); - } catch (error) { - console.log(error); - isButtonDisabledRef.current = true; - setSubmitError('Please enter a valid OTP'); - } - }, - [otp, stateParam, authCallback, redirectURL] - ); - - return ( - - -
- {emailParam && ( - - We have sent an OTP. Please check your inbox at - {emailParam} - - )} - - -
- - - - - {submitError && String(submitError)} - - - - -
- - - Back to login - - - ); -}; diff --git a/web/sdk/react/components/onboarding/magiclink.tsx b/web/sdk/react/components/onboarding/magiclink.tsx deleted file mode 100644 index 2a2fbf657..000000000 --- a/web/sdk/react/components/onboarding/magiclink.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { yupResolver } from '@hookform/resolvers/yup'; -import { Button, Text, Separator, Flex, InputField } from '@raystack/apsara'; -import React, { useCallback, useState } from 'react'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import isEmail from 'validator/lib/isEmail'; -import { HttpErrorResponse } from '~/react/utils'; -import { useMutation, FrontierServiceQueries } from '~hooks'; - -const styles = { - container: { - width: '100%', - display: 'flex', - alignItems: 'center', - gap: 'var(--rs-space-5)' - }, - - button: { - width: '100%' - } -}; - -type MagicLinkProps = { - open?: boolean; - children?: React.ReactNode; -}; - -const emailSchema = yup.object({ - email: yup - .string() - .trim() - .required() - .test( - 'is-valid', - () => 'Please enter a valid email address.', - value => - value ? isEmail(value) : new yup.ValidationError('Invalid value') - ) -}); - -type FormData = yup.InferType; - -export const MagicLink = ({ open = false, ...props }: MagicLinkProps) => { - const { config } = useFrontier(); - const [visible, setVisible] = useState(open); - - const { mutateAsync: authenticate, isPending } = useMutation( - FrontierServiceQueries.authenticate - ); - - const { - watch, - handleSubmit, - setError, - register, - formState: { errors } - } = useForm({ - resolver: yupResolver(emailSchema) - }); - - const magicLinkHandler = useCallback( - async (data: FormData) => { - try { - const response = await authenticate({ - strategyName: 'mailotp', - email: data.email, - callbackUrl: config.callbackUrl - }); - - const searchParams = new URLSearchParams({ - state: response.state || '', - email: data.email - }); - - // @ts-ignore - window.location = `${ - config.redirectMagicLinkVerify - }?${searchParams.toString()}`; - } catch (err: unknown) { - if (err instanceof Response && err?.status === 400) { - const message = - (err as HttpErrorResponse)?.error?.message || 'Bad Request'; - setError('email', { message }); - } else { - setError('email', { message: 'An unexpected error occurred' }); - } - } - }, - [authenticate, config.callbackUrl, config.redirectMagicLinkVerify, setError] - ); - - const email = watch('email', ''); - - if (!visible) - return ( - - ); - - return ( -
- {!open && } - - - - {errors.email && String(errors.email?.message)} - - - - - ); -}; diff --git a/web/sdk/react/components/onboarding/oidc.tsx b/web/sdk/react/components/onboarding/oidc.tsx deleted file mode 100644 index ea6383ec6..000000000 --- a/web/sdk/react/components/onboarding/oidc.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Button, Text } from '@raystack/apsara'; -import React from 'react'; -import GoogleLogo from '~/react/assets/logos/google-logo.svg'; -import { capitalize } from '~/utils'; -// @ts-ignore -import styles from './onboarding.module.css'; - -const oidcLogoMap = new Map([['google', GoogleLogo]]); -type ButtonProps = React.HTMLProps & { - provider: string; -}; - -export const OIDCButton = ({ onClick, provider }: ButtonProps) => ( - -); diff --git a/web/sdk/react/components/onboarding/onboarding.module.css b/web/sdk/react/components/onboarding/onboarding.module.css deleted file mode 100644 index 9106bacad..000000000 --- a/web/sdk/react/components/onboarding/onboarding.module.css +++ /dev/null @@ -1,98 +0,0 @@ -.container { - width: 100%; -} -.container80 { - width: 80%; - display: flex; - flex-direction: column; - gap: var(--rs-space-8); - letter-spacing: 0.4px; -} - -.optInputContainer { - position: relative; -} - -.error { - color: var(--rs-color-foreground-danger-primary); - position: absolute; - top: 100%; - left: 0; - right: 0; -} - -.continue { - color: var(--rs-color-foreground-base-emphasis); -} - -.OIDCContainer { - width: 100%; - gap: var(--rs-space-5); -} - -.redirectLink { - color: var(--rs-color-foreground-accent-primary); -} - -.textFieldCode { - text-align: center; -} - -.updatesContainer { - width: 100%; - max-width: 496px; - padding: var(--rs-space-9); - box-sizing: border-box; -} - - -/* Subscribe page styling */ -.subscribeContainer { - width: 360px; - padding: var(--rs-space-8); - box-sizing: border-box; - box-shadow: var(--rs-shadow-feather); - border: 1px solid var(--rs-color-border-base-primary); - border-radius: var(--rs-radius-2); -} - -.subscribeContainer :global(input::placeholder) { - color: var(--rs-color-foreground-base-secondary); - font-family: var(--rs-font-body); - font-size: var(--rs-font-size-small); - font-style: normal; - font-weight: var(--rs-font-weight-regular); - line-height: var(--rs-line-height-small); - letter-spacing: var(--rs-letter-spacing-small); -} - -.subscribeContainer :global(input) { - color: var(--rs-color-foreground-base-primary); - font-family: var(--rs-font-body); - font-size: var(--rs-font-size-small); - font-style: normal; - font-weight: var(--rs-font-weight-regular); - line-height: var(--rs-line-height-small); - letter-spacing: var(--rs-letter-spacing-small); -} - - -.subscribeTitle { - color: var(--rs-color-foreground-base-primary); - font-family: var(--rs-font-body); - font-size: var(--rs-font-size-large); - font-style: normal; - font-weight: var(--rs-font-weight-medium); - line-height: var(--rs-line-height-large); - letter-spacing: var(--rs-letter-spacing-large); -} - -.subscribeDescription { - color: var(--rs-color-foreground-base-secondary); - font-family: var(--rs-font-body); - font-size: var(--rs-font-size-regular); - font-style: normal; - font-weight: var(--rs-font-weight-regular); - line-height: var(--rs-line-height-regular); - letter-spacing: var(--rs-letter-spacing-regular); -} \ No newline at end of file diff --git a/web/sdk/react/components/onboarding/signin.tsx b/web/sdk/react/components/onboarding/signin.tsx deleted file mode 100644 index efa8e264c..000000000 --- a/web/sdk/react/components/onboarding/signin.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Link, Text, Flex } from '@raystack/apsara'; -import React, { ComponentPropsWithRef, useCallback } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useQuery, useMutation, FrontierServiceQueries } from '~hooks'; -import { Container } from '../Container'; -import { Header } from '../Header'; -import { MagicLink } from './magiclink'; -import { OIDCButton } from './oidc'; - -// @ts-ignore -import styles from './onboarding.module.css'; - -type SignedInProps = ComponentPropsWithRef & { - logo?: React.ReactNode; - title?: string; - excludes?: string[]; - footer?: boolean; -}; -export const SignIn = ({ - logo, - title = 'Login to Raystack', - excludes = [], - footer = true, - ...props -}: SignedInProps) => { - const { config } = useFrontier(); - - const { data: strategiesData } = useQuery( - FrontierServiceQueries.listAuthStrategies - ); - const strategies = strategiesData?.strategies || []; - - const { mutateAsync: authenticate } = useMutation( - FrontierServiceQueries.authenticate - ); - - const clickHandler = useCallback( - async (name?: string) => { - if (!name) return; - try { - const response = await authenticate({ - strategyName: name, - callbackUrl: config.callbackUrl - }); - if (response.endpoint) { - window.location.href = response.endpoint; - } - } catch (error) { - console.error('Authentication failed:', error); - } - }, - [authenticate, config.callbackUrl] - ); - - const mailotp = strategies.find(s => s.name === 'mailotp'); - const filteredOIDC = strategies - .filter(s => s.name !== 'mailotp') - .filter(s => !excludes.includes(s.name ?? '')); - - return ( - -
- - {filteredOIDC.map((s, index) => { - return ( - clickHandler(s.name)} - provider={s.name || ''} - data-test-id="frontier-sdk-oidc-btn" - > - ); - })} - - {mailotp && } - - {footer && ( -
- - Don't have an account?{' '} - - Signup - - -
- )} - - ); -}; diff --git a/web/sdk/react/components/onboarding/signup.tsx b/web/sdk/react/components/onboarding/signup.tsx deleted file mode 100644 index 778b0ad34..000000000 --- a/web/sdk/react/components/onboarding/signup.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { Link, Text, Flex } from '@raystack/apsara'; -import React, { ComponentPropsWithRef, useCallback } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useQuery, useMutation, FrontierServiceQueries } from '~hooks'; -import { Container } from '../Container'; -import { Header } from '../Header'; -import { MagicLink } from './magiclink'; -import { OIDCButton } from './oidc'; - -// @ts-ignore -import styles from './onboarding.module.css'; - -type SignUpProps = ComponentPropsWithRef & { - logo?: React.ReactNode; - title?: string; - excludes?: string[]; -}; -export const SignUp = ({ - logo, - title = 'Create your account', - excludes = [], - ...props -}: SignUpProps) => { - const { config } = useFrontier(); - - const { data: strategiesData } = useQuery( - FrontierServiceQueries.listAuthStrategies - ); - const strategies = strategiesData?.strategies || []; - - const { mutateAsync: authenticate } = useMutation( - FrontierServiceQueries.authenticate - ); - - const clickHandler = useCallback( - async (name?: string) => { - if (!name) return; - try { - const response = await authenticate({ - strategyName: name, - callbackUrl: config.callbackUrl - }); - if (response.endpoint) { - window.location.href = response.endpoint; - } - } catch (error) { - console.error('Authentication failed:', error); - } - }, - [authenticate, config.callbackUrl] - ); - - const mailotp = strategies.find(s => s.name === 'mailotp'); - const filteredOIDC = strategies - .filter(s => s.name !== 'mailotp') - .filter(s => !excludes.includes(s.name ?? '')); - - return ( - -
- - {filteredOIDC.map((s, index) => { - return ( - clickHandler(s.name)} - provider={s.name || ''} - data-test-id="frontier-sdk-signup-page-oidc-btn" - > - ); - })} - - {mailotp && } - -
- - Already have an account?{' '} - - Login - - -
- - ); -}; diff --git a/web/sdk/react/components/onboarding/subscribe.tsx b/web/sdk/react/components/onboarding/subscribe.tsx deleted file mode 100644 index c61147dad..000000000 --- a/web/sdk/react/components/onboarding/subscribe.tsx +++ /dev/null @@ -1,206 +0,0 @@ -'use client'; - -import { ReactNode, useState } from 'react'; -import * as yup from 'yup'; -import { useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; - -import { - Button, - Flex, - Text, - InputField, - toast, - ToastContainer, - Image, - EmptyState -} from '@raystack/apsara'; -import { useMutation, FrontierServiceQueries } from '~hooks'; -import { create } from '@bufbuild/protobuf'; -import { CreateProspectPublicRequestSchema } from '@raystack/proton/frontier'; - -import checkCircle from '~/react/assets/check-circle.svg'; -import styles from './onboarding.module.css'; - -const schema = yup.object({ - name: yup.string().required('Name is required'), - email: yup.string().email('Invalid email').required('Email is required'), - contactNumber: yup - .string() - .transform(value => (value.trim() === '' ? null : value)) - .nullable() - .test( - 'digits-only', - 'Must contain only numbers with country code', - value => { - if (!value?.trim()) return true; - return /^[+\d\s\-()]+$/.test(value); - } - ) - .optional() -}); - -type FormData = yup.InferType; - -interface ExtendedFormData extends FormData { - activity: string; - source?: string; - metadata?: { - medium?: string; - }; -} - -type SubscribeProps = { - title?: string; - desc?: string; - activity?: string; - medium?: string; - source?: string; - confirmSection?: ReactNode; - // eslint-disable-next-line no-unused-vars - onSubmit?: (data: FormData) => void; -}; - -const DEFAULT_TITLE = 'Updates, News & Events'; -const DEFAULT_DESCRIPTION = - 'Stay informed on new features, improvements, and key updates'; -const DEFAULT_SUCCESS_TITLE = 'Thank you for subscribing!'; -const DEFAULT_SUCCESS_DESCRIPTION = - 'You have successfully subscribed to our list. We will let you know about the updates.'; - -const ConfirmSection = () => { - return ( - - - } - heading={DEFAULT_SUCCESS_TITLE} - subHeading={DEFAULT_SUCCESS_DESCRIPTION} - /> - - - ); -}; - -export const Subscribe = ({ - title = DEFAULT_TITLE, - desc = DEFAULT_DESCRIPTION, - activity = 'newsletter', - medium, - source, - confirmSection = , - onSubmit -}: SubscribeProps) => { - const [isSuccess, setIsSuccess] = useState(false); - - const { - register, - handleSubmit, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(schema) - }); - - const { mutateAsync: createProspect } = useMutation( - FrontierServiceQueries.createProspectPublic, - { - onError: (err: Error) => { - console.error('Frontier SDK: Error while submitting the form', err); - toast.error('Something went wrong. Please try again.', { - description: err?.message - }); - } - } - ); - - async function onFormSubmit(data: FormData) { - const formData: ExtendedFormData = { ...data, activity }; - if (medium) { - formData.metadata = { ...formData.metadata, medium }; - } - if (source) { - formData.source = source; - } - - await createProspect( - create(CreateProspectPublicRequestSchema, { - name: formData.name, - email: formData.email, - phone: formData?.contactNumber || undefined, - activity: formData.activity, - source: formData.source, - metadata: formData.metadata - }) - ); - setIsSuccess(true); - onSubmit?.(data); - } - - if (isSuccess) { - return <>{confirmSection}; - } - - return ( - -
- - - - {title} - - - {desc} - - - - - - - - - -
- ); -}; diff --git a/web/sdk/react/components/onboarding/updates.tsx b/web/sdk/react/components/onboarding/updates.tsx deleted file mode 100644 index 713330a03..000000000 --- a/web/sdk/react/components/onboarding/updates.tsx +++ /dev/null @@ -1,107 +0,0 @@ -'use client'; - -import { yupResolver } from '@hookform/resolvers/yup'; -import { type ReactNode } from 'react'; -import { Button, Flex, Text, Switch, Skeleton } from '@raystack/apsara'; -import { Controller, useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { PREFERENCE_OPTIONS } from '~/react/utils/constants'; -import { usePreferences } from '~/react/hooks/usePreferences'; -import { Container } from '../Container'; -import { Header } from '../Header'; -import styles from './onboarding.module.css'; - -const schema = yup.object({ - [PREFERENCE_OPTIONS.NEWSLETTER]: yup.boolean().optional() -}); - -type FormData = yup.InferType; - -type UpdatesProps = { - logo?: ReactNode; - title?: string; - preferenceTitle?: string; - preferenceDescription?: string; - onSubmit?: (data: FormData) => void; -}; - -export const Updates = ({ - logo, - title = 'Subscribe for updates', - preferenceTitle = 'Updates, News & Events', - preferenceDescription = 'Stay informed on new features, improvements, and key updates', - onSubmit -}: UpdatesProps) => { - const { preferences, isFetching, updatePreferences } = usePreferences(); - - const newsletterValue = - preferences?.[PREFERENCE_OPTIONS.NEWSLETTER]?.value === 'true'; - - const { - control, - handleSubmit, - formState: { isSubmitting } - } = useForm({ - values: { - [PREFERENCE_OPTIONS.NEWSLETTER]: newsletterValue - }, - resolver: yupResolver(schema) - }); - - async function onFormSubmit(data: FormData) { - return updatePreferences([ - { - name: PREFERENCE_OPTIONS.NEWSLETTER, - value: String(data[PREFERENCE_OPTIONS.NEWSLETTER]) - } - ]) - .then(() => onSubmit?.(data)) - .catch(err => { - console.error('frontier:sdk:: error during submit', err); - }); - } - return ( - -
-
- - - - - {preferenceTitle} - - {isFetching ? ( - - ) : ( - ( - - )} - control={control} - name={PREFERENCE_OPTIONS.NEWSLETTER} - /> - )} - - - {preferenceDescription} - - - - -
- - ); -}; diff --git a/web/sdk/react/components/organization/api-keys/index.tsx b/web/sdk/react/components/organization/api-keys/index.tsx deleted file mode 100644 index d178c705a..000000000 --- a/web/sdk/react/components/organization/api-keys/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -'use client'; - -import { useNavigate } from '@tanstack/react-router'; -import { ApiKeysListPage } from '~/react/views/api-keys'; - -export default function APIKeys() { - const navigate = useNavigate({ from: '/api-keys' }); - - return ( - - navigate({ - to: '/api-keys/$id', - params: { id } - }) - } - /> - ); -} diff --git a/web/sdk/react/components/organization/api-keys/service-user/index.tsx b/web/sdk/react/components/organization/api-keys/service-user/index.tsx deleted file mode 100644 index d18810ea9..000000000 --- a/web/sdk/react/components/organization/api-keys/service-user/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client'; - -import { useNavigate, useParams, useLocation } from '@tanstack/react-router'; -import { ServiceUserDetailPage } from '~/react/views/api-keys'; - -export default function ServiceUserPage() { - const { id } = useParams({ from: '/api-keys/$id' }); - const navigate = useNavigate({ from: '/api-keys/$id' }); - const location = useLocation(); - - return ( - navigate({ to: '/api-keys' })} - enableTokensFetch={location.state?.enableServiceUserTokensListFetch} - /> - ); -} diff --git a/web/sdk/react/components/organization/billing/index.tsx b/web/sdk/react/components/organization/billing/index.tsx deleted file mode 100644 index 7d575ad57..000000000 --- a/web/sdk/react/components/organization/billing/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -'use client'; - -import { useNavigate } from '@tanstack/react-router'; -import { BillingPage } from '~/react/views/billing'; - -export default function Billing() { - const navigate = useNavigate({ from: '/billing' }); - - return ( - navigate({ to: '/plans' })} - /> - ); -} diff --git a/web/sdk/react/components/organization/create.tsx b/web/sdk/react/components/organization/create.tsx deleted file mode 100644 index 21d55d82e..000000000 --- a/web/sdk/react/components/organization/create.tsx +++ /dev/null @@ -1,114 +0,0 @@ -'use client'; - -import { yupResolver } from '@hookform/resolvers/yup'; -import { Button, Text, Headline, Flex, InputField, toast } from '@raystack/apsara'; -import { ComponentPropsWithRef } from 'react'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { Container } from '../Container'; -import { useMutation, FrontierServiceQueries } from '~hooks'; -import { create } from '@bufbuild/protobuf'; -import { CreateOrganizationRequestSchema } from '@raystack/proton/frontier'; - -// @ts-ignore -import styles from './organization.module.css'; -import { useTerminology } from '~/react/hooks/useTerminology'; - -type CreateOrganizationProps = ComponentPropsWithRef & { - title?: string; - description?: string; -}; - -const schema = yup - .object({ - title: yup.string().required(), - name: yup.string().required() - }) - .required(); - -export const CreateOrganization = ({ - title = 'Create a new organization', - description = 'Organizations are shared environments where team can work on assets, connections and data operations.', - ...props -}: CreateOrganizationProps) => { - const t = useTerminology(); - const { - handleSubmit, - formState: { errors, isSubmitting }, - register - } = useForm>({ - resolver: yupResolver(schema) - }); - - const { mutateAsync: createOrganization } = useMutation( - FrontierServiceQueries.createOrganization, - { - onError: (err: Error) => { - toast.error('Failed to create organization', { - description: err?.message - }); - } - } - ); - - async function onSubmit(data: yup.InferType) { - const response = await createOrganization( - create(CreateOrganizationRequestSchema, { - body: { - title: data.title, - name: data.name - } - }) - ); - const organization = response.organization; - if (organization?.name) { - // @ts-ignore - window.location = `${window.location.origin}/${organization.name}`; - } - } - - return ( - - - - {title} - - {description} - - -
- - - - - -
-
-
- ); -}; diff --git a/web/sdk/react/components/organization/domain/add-domain.tsx b/web/sdk/react/components/organization/domain/add-domain.tsx deleted file mode 100644 index 2645cd394..000000000 --- a/web/sdk/react/components/organization/domain/add-domain.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { - Button, - Image, - Text, - Flex, - toast, - Dialog, - InputField -} from '@raystack/apsara'; - -import { yupResolver } from '@hookform/resolvers/yup'; -import { useNavigate } from '@tanstack/react-router'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation, createConnectQueryKey, useTransport } from '@connectrpc/connect-query'; -import { useQueryClient } from '@tanstack/react-query'; -import { FrontierServiceQueries, CreateOrganizationDomainRequestSchema, ListOrganizationDomainsRequestSchema } from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; -import cross from '~/react/assets/cross.svg'; -import styles from '../organization.module.css'; - -const domainSchema = yup - .object({ - domain: yup - .string() - .required() - .matches(/[-a-zA-Z0-9.]{1,256}\.[a-zA-Z0-9()]{1,6}$/, 'Domain is invalid') - }) - .required(); - -type FormData = yup.InferType; - -export const AddDomain = () => { - const { - register, - handleSubmit, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(domainSchema) - }); - const navigate = useNavigate({ from: '/domains/modal' }); - const { activeOrganization: organization } = useFrontier(); - const queryClient = useQueryClient(); - const transport = useTransport(); - - const { mutateAsync: createOrganizationDomain } = useMutation( - FrontierServiceQueries.createOrganizationDomain, - { - onSuccess: async (data) => { - toast.success('Domain successfully added'); - // Invalidate domains list to refetch - if (organization?.id) { - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listOrganizationDomains, - transport, - input: create(ListOrganizationDomainsRequestSchema, { - orgId: organization.id - }), - cardinality: 'finite' - }) - }); - } - navigate({ - to: `/domains/$domainId/verify`, - params: { domainId: data?.domain?.id ?? '' } - }); - }, - onError: (error: Error) => { - toast.error('Something went wrong', { - description: error.message - }); - } - } - ); - - async function onSubmit(data: FormData) { - if (!organization?.id) return; - - await createOrganizationDomain( - create(CreateOrganizationDomainRequestSchema, { - orgId: organization.id, - domain: data.domain - }) - ); - } - - return ( - - -
- - - - Add domain - - - cross navigate({ to: '/domains' })} - data-test-id="frontier-sdk-add-domain-btn" - /> - - - - - - - - - - - - - - -
-
-
- ); -}; diff --git a/web/sdk/react/components/organization/domain/delete.tsx b/web/sdk/react/components/organization/domain/delete.tsx deleted file mode 100644 index 1f843cd2d..000000000 --- a/web/sdk/react/components/organization/domain/delete.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { - Button, - Checkbox, - Skeleton, - Text, - Flex, - toast, - InputField, - Dialog -} from '@raystack/apsara'; - -import { useEffect } from 'react'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { useNavigate, useParams } from '@tanstack/react-router'; -import { useState } from 'react'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation, createConnectQueryKey, useTransport } from '@connectrpc/connect-query'; -import { useQueryClient } from '@tanstack/react-query'; -import { FrontierServiceQueries, - DeleteOrganizationDomainRequestSchema, - ListOrganizationDomainsRequestSchema -} from '@raystack/proton/frontier'; -import { useOrganizationDomain } from '~/react/hooks/useOrganizationDomain'; -import { create } from '@bufbuild/protobuf'; -import styles from '../organization.module.css'; - -const domainSchema = yup - .object({ - domain: yup - .string() - .required() - .matches(/[-a-zA-Z0-9.]{1,256}\.[a-zA-Z0-9()]{1,6}$/, 'Domain is invalid') - }) - .required(); - -type FormData = yup.InferType; - -export const DeleteDomain = () => { - const { - watch, - handleSubmit, - setError, - formState: { errors }, - register - } = useForm({ - resolver: yupResolver(domainSchema) - }); - const navigate = useNavigate({ from: '/domains/$domainId/delete' }); - const { domainId } = useParams({ from: '/domains/$domainId/delete' }); - const { activeOrganization: organization } = useFrontier(); - const queryClient = useQueryClient(); - const transport = useTransport(); - const [isAcknowledged, setIsAcknowledged] = useState(false); - - const { domain, isLoading, error: domainError } = useOrganizationDomain(domainId); - - useEffect(() => { - if (domainError) { - toast.error('Something went wrong', { - description: (domainError as Error).message - }); - } - }, [domainError]); - - const { mutateAsync: deleteOrganizationDomain, isPending } = useMutation( - FrontierServiceQueries.deleteOrganizationDomain, - { - onSuccess: async () => { - toast.success('Domain successfully deleted'); - // Invalidate domains list to refetch - if (organization?.id) { - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listOrganizationDomains, - transport, - input: create(ListOrganizationDomainsRequestSchema, { - orgId: organization.id - }), - cardinality: 'finite' - }) - }); - } - navigate({ to: '/domains' }); - }, - onError: (error: Error) => { - toast.error('Something went wrong', { - description: error.message - }); - } - } - ); - - async function onSubmit(data: FormData) { - if (!domain?.id || !organization?.id) return; - - if (data.domain !== domain.name) { - return setError('domain', { message: 'Domain name does not match' }); - } - - await deleteOrganizationDomain( - create(DeleteOrganizationDomainRequestSchema, { - id: domain.id, - orgId: organization.id - }) - ); - } - - const domainName = watch('domain', ''); - - return ( - - - - Verify domain deletion - - navigate({ - to: `/domains` - }) - } - data-test-id="frontier-sdk-delete-domain-close-btn" - /> - -
- - - {isLoading ? ( - <> - - - - - - - ) : ( - <> - - This action can not be undone. This will permanently delete{' '} - {domain?.name}. - - - - - - setIsAcknowledged(v === true)} - data-test-id="frontier-sdk-delete-domain-checkbox" - /> - - I acknowledge and understand that all of the domain data will - be deleted and want to proceed. - - - - - - )} - - -
-
-
- ); -}; diff --git a/web/sdk/react/components/organization/domain/domain.columns.tsx b/web/sdk/react/components/organization/domain/domain.columns.tsx deleted file mode 100644 index ba8c70d1d..000000000 --- a/web/sdk/react/components/organization/domain/domain.columns.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { CheckCircledIcon, TrashIcon } from '@radix-ui/react-icons'; -import { Button, Text, Flex, type DataTableColumnDef } from '@raystack/apsara'; -import { useNavigate } from '@tanstack/react-router'; -import type { Domain } from '@raystack/proton/frontier'; -import dayjs from 'dayjs'; - -interface getColumnsOptions { - canCreateDomain?: boolean; - dateFormat: string; -} - -export const getColumns: ( - options: getColumnsOptions -) => DataTableColumnDef[] = ({ - canCreateDomain, - dateFormat -}) => [ - { - header: 'Name', - accessorKey: 'name', - meta: { - style: { - paddingLeft: 0 - } - }, - cell: ({ row, getValue }) => { - return ( - - {row.original.name} - - ); - } - }, - { - header: 'Created at', - accessorKey: 'created_at', - cell: info => ( - - {dayjs(info.getValue() as string).format(`${dateFormat}, hh:mmA`)} - - ) - }, - { - header: '', - accessorKey: 'id', - meta: { - style: { - textAlign: 'end' - } - }, - enableSorting: false, - cell: ({ row, getValue }) => ( - - ) - } -]; - -const DomainActions = ({ - domain, - canCreateDomain -}: { - domain: Domain; - canCreateDomain?: boolean; -}) => { - const navigate = useNavigate({ from: '/domains' }); - - return canCreateDomain ? ( - - {domain.state === 'pending' ? ( - - ) : ( - - - Verified - - )} - - - navigate({ - to: `/domains/$domainId/delete`, - params: { - domainId: domain?.id || '' - } - }) - } - color="var(--rs-color-foreground-danger-primary)" - style={{ cursor: 'pointer' }} - /> - - ) : null; -}; diff --git a/web/sdk/react/components/organization/domain/domain.module.css b/web/sdk/react/components/organization/domain/domain.module.css deleted file mode 100644 index 4c7cc73c9..000000000 --- a/web/sdk/react/components/organization/domain/domain.module.css +++ /dev/null @@ -1,23 +0,0 @@ -.tableWrapper { - display: flex; - flex-direction: column; - flex: 1; - min-height: 0; - overflow: hidden; -} - -.tableRoot { - flex: 1; - overflow-y: auto; - overflow-x: hidden; - min-height: 0; -} - -.tableHeader { - z-index: 1; -} - -.tableSearchWrapper { - max-width: 500px; - flex: 1; -} diff --git a/web/sdk/react/components/organization/domain/index.tsx b/web/sdk/react/components/organization/domain/index.tsx deleted file mode 100644 index 761b2a81d..000000000 --- a/web/sdk/react/components/organization/domain/index.tsx +++ /dev/null @@ -1,181 +0,0 @@ -'use client'; - -import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; -import { - Button, - Tooltip, - EmptyState, - Skeleton, - Flex, - DataTable, - toast -} from '@raystack/apsara'; -import { Outlet, useNavigate } from '@tanstack/react-router'; -import { useEffect, useMemo } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useOrganizationDomains } from '~/react/hooks/useOrganizationDomains'; -import { usePermissions } from '~/react/hooks/usePermissions'; -import { type Domain as DomainType } from '@raystack/proton/frontier'; -import { PERMISSIONS, shouldShowComponent } from '~/utils'; -import { getColumns } from './domain.columns'; -import { AuthTooltipMessage } from '~/react/utils'; -import { DEFAULT_DATE_FORMAT } from '~/react/utils/constants'; -import { PageHeader } from '~/react/components/common/page-header'; -import sharedStyles from '../styles.module.css'; -import styles from './domain.module.css'; -import { useTerminology } from '~/react/hooks/useTerminology'; - -export default function Domain() { - const { isFetching, domains, error: domainsError } = useOrganizationDomains(); - const { activeOrganization: organization, config } = useFrontier(); - const t = useTerminology(); - - useEffect(() => { - if (domainsError) { - toast.error('Something went wrong', { - description: (domainsError as Error).message - }); - } - }, [domainsError]); - - const resource = `app/organization:${organization?.id}`; - const listOfPermissionsToCheck = useMemo( - () => [ - { - permission: PERMISSIONS.UpdatePermission, - resource - } - ], - [resource] - ); - - const { permissions, isFetching: isPermissionsFetching } = usePermissions( - listOfPermissionsToCheck, - !!organization?.id - ); - - const { canCreateDomain } = useMemo(() => { - return { - canCreateDomain: shouldShowComponent( - permissions, - `${PERMISSIONS.UpdatePermission}::${resource}` - ) - }; - }, [permissions, resource]); - - const isLoading = isFetching || isPermissionsFetching; - - return ( - - - - - - - - - - - - ); -} - -const Domains = ({ - domains = [], - isLoading, - canCreateDomain, - dateFormat -}: { - domains: DomainType[]; - isLoading?: boolean; - canCreateDomain?: boolean; - dateFormat?: string; -}) => { - const navigate = useNavigate({ from: '/domains' }); - - const columns = useMemo( - () => - getColumns({ - canCreateDomain, - dateFormat: dateFormat || DEFAULT_DATE_FORMAT - }), - [canCreateDomain, dateFormat] - ); - - return ( - - - - - {isLoading ? ( - - ) : ( - - )} - - {isLoading ? ( - - ) : ( - - - - )} - - - - - ); -}; - -const noDataChildren = ( - } - heading="No domains found" - subHeading="Get started by adding your first domain." - /> -); diff --git a/web/sdk/react/components/organization/domain/verify-domain.tsx b/web/sdk/react/components/organization/domain/verify-domain.tsx deleted file mode 100644 index 8e0914f30..000000000 --- a/web/sdk/react/components/organization/domain/verify-domain.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import { - Button, - Skeleton, - Image, - Text, - Flex, - toast, - Dialog, - CopyButton -} from '@raystack/apsara'; - -import { useEffect } from 'react'; -import { useNavigate, useParams } from '@tanstack/react-router'; -import { useQueryClient } from '@tanstack/react-query'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation, createConnectQueryKey, useTransport } from '@connectrpc/connect-query'; -import { FrontierServiceQueries, - VerifyOrganizationDomainRequestSchema, - ListOrganizationDomainsRequestSchema -} from '@raystack/proton/frontier'; -import { useOrganizationDomain } from '~/react/hooks/useOrganizationDomain'; -import { create } from '@bufbuild/protobuf'; -import cross from '~/react/assets/cross.svg'; -import styles from '../organization.module.css'; - -export const VerifyDomain = () => { - const navigate = useNavigate({ from: '/domains/$domainId/verify' }); - const { domainId } = useParams({ from: '/domains/$domainId/verify' }); - const { activeOrganization: organization } = useFrontier(); - const queryClient = useQueryClient(); - const transport = useTransport(); - - const { domain, isLoading: isDomainLoading, error: domainError } = useOrganizationDomain(domainId); - - useEffect(() => { - if (domainError) { - toast.error('Something went wrong', { - description: (domainError as Error).message - }); - } - }, [domainError]); - - const { mutateAsync: verifyOrganizationDomain, isPending: isVerifying } = useMutation( - FrontierServiceQueries.verifyOrganizationDomain, - { - onSuccess: async () => { - toast.success('Domain verified'); - // Invalidate domains list to refetch - if (organization?.id) { - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listOrganizationDomains, - transport, - input: create(ListOrganizationDomainsRequestSchema, { - orgId: organization.id - }), - cardinality: 'finite' - }) - }); - } - navigate({ to: '/domains' }); - }, - onError: (error: Error) => { - toast.error('Something went wrong', { - description: error.message - }); - } - } - ); - - async function handleVerify() { - if (!domainId || !organization?.id) return; - - await verifyOrganizationDomain( - create(VerifyOrganizationDomainRequestSchema, { - orgId: organization.id, - id: domainId - }) - ); - } - - return ( - - - - - - Verify domain - - - cross navigate({ to: '/domains' })} - data-test-id="frontier-sdk-verify-domain-close-btn" - /> - - - - - - {isDomainLoading ? ( - <> - - - - - ) : ( - <> - - Before we can verify {domain?.name}, you'll need to - create a TXT record in your DNS configuration for this - hostname. - - - - {domain?.token} - - {domain?.token && ( - - )} - - - Wait until your DNS configuration changes. This could take up - to 72 hours to propagate. - - - )} - - - - - - {isDomainLoading ? ( - - ) : ( - - )} - - - - - ); -}; diff --git a/web/sdk/react/components/organization/general/index.tsx b/web/sdk/react/components/organization/general/index.tsx deleted file mode 100644 index 54665016b..000000000 --- a/web/sdk/react/components/organization/general/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -'use client'; - -import { GeneralPage } from '~/react/views/general'; - -export default function GeneralSetting() { - return { - // @ts-ignore - window.location = window.location.origin; - }}/>; -} diff --git a/web/sdk/react/components/organization/members/index.tsx b/web/sdk/react/components/organization/members/index.tsx deleted file mode 100644 index 4ed5a0faf..000000000 --- a/web/sdk/react/components/organization/members/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import { MembersPage } from '~/react/views/members'; - -export default function WorkspaceMembers() { - return ; -} diff --git a/web/sdk/react/components/organization/organization.module.css b/web/sdk/react/components/organization/organization.module.css deleted file mode 100644 index 7e5934346..000000000 --- a/web/sdk/react/components/organization/organization.module.css +++ /dev/null @@ -1,43 +0,0 @@ -.createContainer { - margin: auto; - width: 100%; - max-width: 384px; - padding: var(--rs-space-9); -} - -.overlay { - z-index: var(--rs-z-index-portal); - background-color: rgba(104, 112, 118, 0.5); -} - -.dropdownActionItem { - cursor: pointer; - gap: var(--rs-space-3); - display: flex; - align-items: center; - text-decoration: none; - color: var(--rs-color-foreground-base-primary); - background: var(--rs-color-background-base-primary); - padding: var(--rs-space-3); - flex: 1; -} - -.dropdownActionItem:hover { - background: var(--rs-color-background-base-primary-hover); - color: var(--rs-color-foreground-base-primary); -} - -.noSelectItem { - color: var(--rs-color-foreground-base-secondary); - padding: var(--rs-space-3); -} - -.orgTabsContainer { - box-sizing: border-box; -} - -.invite-member-emails-textarea { - resize: vertical; - width: 100%; - max-height: var(--rs-space-17); -} diff --git a/web/sdk/react/components/organization/plans/index.tsx b/web/sdk/react/components/organization/plans/index.tsx deleted file mode 100644 index 490b7995b..000000000 --- a/web/sdk/react/components/organization/plans/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import { PlansPage } from '~/react/views/plans'; - -export default function Plans() { - return ; -} diff --git a/web/sdk/react/components/organization/preferences/index.tsx b/web/sdk/react/components/organization/preferences/index.tsx deleted file mode 100644 index 207758bc8..000000000 --- a/web/sdk/react/components/organization/preferences/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -'use client'; - -import { useRouteContext } from '@tanstack/react-router'; -import { PreferencesPage } from '~/react/views/preferences'; -import { RouterContext } from '../routes'; - -export default function UserPreferences() { - const { theme, onThemeChange } = useRouteContext({ from: '__root__' }) as RouterContext; - return ; -} diff --git a/web/sdk/react/components/organization/profile.tsx b/web/sdk/react/components/organization/profile.tsx deleted file mode 100644 index e1ad8ee32..000000000 --- a/web/sdk/react/components/organization/profile.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useMemo } from 'react'; -import { - RouterProvider, - createMemoryHistory, - createRouter -} from '@tanstack/react-router'; -import { - getCustomRoutes, - getRootTree, - OrganizationProfileProps -} from './routes'; - -const router = createRouter({ - routeTree: getRootTree({}), - context: { - organizationId: '', - showBilling: false, - showTokens: false, - showAPIKeys: false, - showPreferences: false, - customRoutes: { Organization: [], User: [] } - } -}); - -export const OrganizationProfile = ({ - organizationId, - defaultRoute = '/', - showBilling = false, - showTokens = false, - showAPIKeys = false, - showPreferences = false, - hideToast = false, - customScreens = [], - onLogout = () => { }, - theme, - onThemeChange, -}: OrganizationProfileProps) => { - const memoryHistory = createMemoryHistory({ - initialEntries: [defaultRoute] - }); - - const customRoutes = getCustomRoutes(customScreens); - - const routeTree = getRootTree({ customScreens }); - - const memoryRouter = useMemo( - () => - createRouter({ - routeTree, - history: memoryHistory, - context: { - organizationId, - showBilling, - showTokens, - showAPIKeys, - hideToast, - showPreferences, - customRoutes, - onLogout, - theme, - onThemeChange - } - }), - // Router is created once; dynamic context flows through RouterProvider's - // context prop so updates don't recreate the router and reset navigation. - // eslint-disable-next-line react-hooks/exhaustive-deps - [] - ); - - return ( - - ); -}; - -declare module '@tanstack/react-router' { - interface Register { - router: typeof router; - } - - interface HistoryState { - refetch?: boolean; - enableServiceUserTokensListFetch?: boolean; - } -} diff --git a/web/sdk/react/components/organization/project/index.tsx b/web/sdk/react/components/organization/project/index.tsx deleted file mode 100644 index 95cdf0a80..000000000 --- a/web/sdk/react/components/organization/project/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -'use client'; - -import { useNavigate } from '@tanstack/react-router'; -import { ProjectsListPage } from '~/react/views/projects'; - -export default function WorkspaceProjects() { - const navigate = useNavigate({ from: '/projects' }); - - return ( - - navigate({ to: '/projects/$projectId', params: { projectId } }) - } - /> - ); -} diff --git a/web/sdk/react/components/organization/project/project.tsx b/web/sdk/react/components/organization/project/project.tsx deleted file mode 100644 index 74b066ad3..000000000 --- a/web/sdk/react/components/organization/project/project.tsx +++ /dev/null @@ -1,16 +0,0 @@ -'use client'; - -import { useNavigate, useParams } from '@tanstack/react-router'; -import { ProjectDetailPage } from '~/react/views/projects'; - -export const ProjectPage = () => { - const { projectId } = useParams({ from: '/projects/$projectId' }); - const navigate = useNavigate({ from: '/projects/$projectId' }); - - return ( - navigate({ to: '/projects' })} - /> - ); -}; diff --git a/web/sdk/react/components/organization/routes.tsx b/web/sdk/react/components/organization/routes.tsx deleted file mode 100644 index 417f19bf2..000000000 --- a/web/sdk/react/components/organization/routes.tsx +++ /dev/null @@ -1,285 +0,0 @@ -import { useEffect } from 'react'; -import { - Outlet, - createRoute, - createRootRouteWithContext, - useRouteContext, - RouteComponent -} from '@tanstack/react-router'; -import { Flex, ToastContainer } from '@raystack/apsara'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useQuery, FrontierServiceQueries } from '~hooks'; -import Domain from './domain'; -import { AddDomain } from './domain/add-domain'; -import { VerifyDomain } from './domain/verify-domain'; -import GeneralSetting from './general'; -import WorkspaceMembers from './members'; -import UserPreferences from './preferences'; - -import { default as WorkspaceProjects } from './project'; -import { ProjectPage } from './project/project'; - -import WorkspaceSecurity from './security'; -import { Sidebar } from './sidebar'; -import WorkspaceTeams from './teams'; -import { TeamPage } from './teams/team'; -import { UserSetting } from './user'; -import { DeleteDomain } from './domain/delete'; -import Billing from './billing'; -import Tokens from './tokens'; -import Plans from './plans'; -import APIKeys from './api-keys'; -import ServiceUserPage from './api-keys/service-user'; -import { SessionsPage } from './sessions'; -export interface CustomScreen { - name: string; - path: string; - category: 'Organization' | 'User'; - component: RouteComponent; -} - -export type Theme = 'light' | 'dark' | 'system'; - -export interface OrganizationProfileProps { - organizationId: string; - defaultRoute?: string; - showBilling?: boolean; - showTokens?: boolean; - showAPIKeys?: boolean; - showPreferences?: boolean; - hideToast?: boolean; - customScreens?: CustomScreen[]; - onLogout?: () => void; - theme?: Theme; - onThemeChange?: (theme: Theme) => void; -} - -export interface CustomRoutes { - Organization: Pick[]; - User: Pick[]; -} - -export type RouterContext = Pick< - OrganizationProfileProps, - | 'organizationId' - | 'showBilling' - | 'showTokens' - | 'showAPIKeys' - | 'hideToast' - | 'showPreferences' - | 'theme' - | 'onThemeChange' -> & { customRoutes: CustomRoutes; onLogout?: () => void }; - -export function getCustomRoutes(customScreens: CustomScreen[] = []) { - return ( - customScreens?.reduce( - (acc: CustomRoutes, { name, category, path }) => { - acc[category].push({ name, path }); - return acc; - }, - { Organization: [], User: [] } - ) || { Organization: [], User: [] } - ); -} - -const RootRouter = () => { - const { organizationId, hideToast } = useRouteContext({ from: '__root__' }); - const { setActiveOrganization, setIsActiveOrganizationLoading } = - useFrontier(); - - const { - data: organizationData, - isLoading, - error - } = useQuery( - FrontierServiceQueries.getOrganization, - { id: organizationId }, - { enabled: !!organizationId } - ); - - useEffect(() => { - setIsActiveOrganizationLoading(isLoading); - }, [isLoading, setIsActiveOrganizationLoading]); - - useEffect(() => { - if (organizationId) { - setActiveOrganization(organizationData?.organization); - } else { - setActiveOrganization(undefined); - } - }, [organizationId, organizationData?.organization, setActiveOrganization]); - - useEffect(() => { - if (error) { - console.error('Failed to fetch organization:', error); - } - }, [error]); - - const visibleToasts = hideToast ? 0 : 1; - - return ( - <> - - - - - - - ); -}; - -const rootRoute = createRootRouteWithContext()({ - component: RootRouter -}); -const indexRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/', - component: GeneralSetting -}); - -const securityRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/security', - component: WorkspaceSecurity -}); - -const membersRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/members', - component: WorkspaceMembers -}); - -const teamsRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/teams', - component: WorkspaceTeams -}); - -const domainsRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/domains', - component: Domain -}); - -const verifyDomainRoute = createRoute({ - getParentRoute: () => domainsRoute, - path: '/$domainId/verify', - component: VerifyDomain -}); - -const deleteDomainRoute = createRoute({ - getParentRoute: () => domainsRoute, - path: '/$domainId/delete', - component: DeleteDomain -}); - -const addDomainRoute = createRoute({ - getParentRoute: () => domainsRoute, - path: '/modal', - component: AddDomain -}); - -const teamRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/teams/$teamId', - component: TeamPage -}); - -const projectsRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/projects', - component: WorkspaceProjects -}); - -const projectPageRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/projects/$projectId', - component: ProjectPage -}); - -const profileRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/profile', - component: UserSetting -}); - -const preferencesRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/preferences', - component: UserPreferences -}); - -const billingRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/billing', - component: Billing -}); - -const plansRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/plans', - component: Plans -}); - - -const tokensRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/tokens', - component: Tokens -}); - -const apiKeysRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/api-keys', - component: APIKeys -}); - -const serviceAccountRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/api-keys/$id', - component: ServiceUserPage -}); - -const sessionsRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions', - component: SessionsPage -}); - - -interface getRootTreeOptions { - customScreens?: CustomScreen[]; -} - -export function getRootTree({ customScreens = [] }: getRootTreeOptions) { - return rootRoute.addChildren([ - indexRoute, - securityRoute, - sessionsRoute, - membersRoute, - teamsRoute, - domainsRoute.addChildren([ - addDomainRoute, - verifyDomainRoute, - deleteDomainRoute - ]), - teamRoute, - projectsRoute, - projectPageRoute, - profileRoute, - preferencesRoute, - billingRoute, - plansRoute, - tokensRoute, - apiKeysRoute, - serviceAccountRoute, - ...customScreens.map(cc => - createRoute({ - path: cc.path, - component: cc.component, - getParentRoute: () => rootRoute - }) - ) - ]); -} diff --git a/web/sdk/react/components/organization/security/index.tsx b/web/sdk/react/components/organization/security/index.tsx deleted file mode 100644 index b0444e866..000000000 --- a/web/sdk/react/components/organization/security/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import { SecurityPage } from '~/react/views/security'; - -export default function WorkspaceSecurity() { - return ; -} diff --git a/web/sdk/react/components/organization/sessions/index.tsx b/web/sdk/react/components/organization/sessions/index.tsx deleted file mode 100644 index d3dcb6099..000000000 --- a/web/sdk/react/components/organization/sessions/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -'use client'; - -import { useRouteContext } from '@tanstack/react-router'; -import { SessionsPage as SessionsPageView } from '~/react/views/sessions'; - -export const SessionsPage = () => { - const { onLogout } = useRouteContext({ from: '__root__' }) as { onLogout?: () => void }; - return ; -}; diff --git a/web/sdk/react/components/organization/shared/types.ts b/web/sdk/react/components/organization/shared/types.ts deleted file mode 100644 index 7ffa037f7..000000000 --- a/web/sdk/react/components/organization/shared/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type OnNavigate = (to: string, params?: Record) => void; - -export interface BasePageProps { - organizationId: string; - onNavigate?: OnNavigate; -} - diff --git a/web/sdk/react/components/organization/sidebar/helpers.ts b/web/sdk/react/components/organization/sidebar/helpers.ts deleted file mode 100644 index 11fafdd5b..000000000 --- a/web/sdk/react/components/organization/sidebar/helpers.ts +++ /dev/null @@ -1,113 +0,0 @@ -import React from 'react'; - -export type NavigationItemsTypes = { - active?: boolean; - to?: string; - name: string; - icon?: React.ReactNode; -}; - -type CustomRoutes = Array<{ name: string; path: string }>; - -interface getOrganizationNavItemsOptions { - showBilling?: boolean; - showTokens?: boolean; - showAPIKeys?: boolean; - canSeeBilling?: boolean; - customRoutes?: CustomRoutes; -} - -interface getUserNavItemsOptions { - showPreferences?: boolean; - customRoutes?: CustomRoutes; -} - -function getCustomRoutes(customRoutes: CustomRoutes = []) { - return ( - customRoutes?.map(r => ({ - name: r.name, - to: r.path, - show: true - })) || [] - ); -} - -export const getOrganizationNavItems = ( - options: getOrganizationNavItemsOptions = {} -) => { - const routes = [ - { - name: 'General', - to: '/', - show: true - }, - { - name: 'Members', - to: '/members', - show: true - }, - { - name: 'Teams', - to: '/teams', - show: true - }, - { - name: 'Projects', - to: '/projects', - show: true - }, - { - name: 'Security', - to: '/domains', - show: true - }, - { - name: 'Billing', - to: '/billing', - show: options?.showBilling && options?.canSeeBilling - }, - { - name: 'Tokens', - to: '/tokens', - show: options?.showTokens - }, - { - name: 'Plans', - to: '/plans', - show: options?.showBilling - }, - { - name: 'API', - to: '/api-keys', - show: options?.showAPIKeys - } - ]; - const customRoutes = getCustomRoutes(options?.customRoutes); - return [...routes, ...customRoutes].filter( - nav => nav.show - ) as NavigationItemsTypes[]; -}; - -export const getUserNavItems = (options: getUserNavItemsOptions = {}) => { - const routes = [ - { - name: 'Profile', - to: '/profile', - show: true - }, - { - name: 'Preferences', - to: '/preferences', - show: options?.showPreferences - }, - { - name: 'Sessions', - to: '/sessions', - show: true - }, - ]; - const customRoutes = getCustomRoutes(options?.customRoutes); - return [...routes, ...customRoutes].filter( - nav => nav.show - ) as NavigationItemsTypes[]; -}; diff --git a/web/sdk/react/components/organization/sidebar/index.tsx b/web/sdk/react/components/organization/sidebar/index.tsx deleted file mode 100644 index fd0720be4..000000000 --- a/web/sdk/react/components/organization/sidebar/index.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import { - Image, - Sidebar as SidebarComponent, - Flex, - Search -} from '@raystack/apsara'; -import { Link, useRouteContext, useRouterState } from '@tanstack/react-router'; -import React, { useCallback, useMemo, useState } from 'react'; -import organization from '~/react/assets/organization.png'; -import user from '~/react/assets/user.png'; -import { getOrganizationNavItems, getUserNavItems } from './helpers'; - -import { usePermissions } from '~/react/hooks/usePermissions'; -import { PERMISSIONS, shouldShowComponent } from '~/utils'; -import styles from './sidebar.module.css'; -import { useTerminology } from '~/react/hooks/useTerminology'; - -export const Sidebar = () => { - const [search, setSearch] = useState(''); - const routerState = useRouterState(); - const t = useTerminology(); - const { - organizationId, - showBilling, - showTokens, - showAPIKeys, - showPreferences, - customRoutes - } = useRouteContext({ - from: '__root__' - }); - - const isActive = useCallback( - (path: string) => - path.length > 2 - ? routerState.location.pathname.includes(path) - : routerState.location.pathname === path, - [routerState.location.pathname] - ); - - const resource = `app/organization:${organizationId}`; - const listOfPermissionsToCheck = useMemo( - () => [ - { - permission: PERMISSIONS.UpdatePermission, - resource - } - ], - [resource] - ); - - const { permissions, isFetching: isPermissionsFetching } = usePermissions( - listOfPermissionsToCheck, - !!organizationId - ); - - const { canSeeBilling } = useMemo(() => { - return { - canSeeBilling: shouldShowComponent( - permissions, - `${PERMISSIONS.UpdatePermission}::${resource}` - ) - }; - }, [permissions, resource]); - - const organizationNavItems = useMemo( - () => - getOrganizationNavItems({ - showBilling: showBilling, - canSeeBilling: canSeeBilling, - showTokens: showTokens, - showAPIKeys: showAPIKeys, - customRoutes: customRoutes.Organization - }), - [ - showBilling, - canSeeBilling, - showTokens, - showAPIKeys, - customRoutes.Organization - ] - ); - - const userNavItems = useMemo( - () => - getUserNavItems({ - showPreferences: showPreferences, - customRoutes: customRoutes.User - }), - [customRoutes.User, showPreferences] - ); - - return ( - -
- - setSearch(event.target.value)} - placeholder="Search pages" - showClearButton - onClear={() => setSearch('')} - data-test-id="frontier-sdk-sidebar-search-field" - /> - - - - } - className={styles.sidebarItemGroupContainer} - > - - {organizationNavItems - .filter(s => s.name.toLowerCase().includes(search)) - .map(nav => { - return ( - - } - active={!!isActive(nav?.to as string)} - > - {nav.name} - - ); - })} - - - - } - className={styles.sidebarItemGroupContainer} - > - - {userNavItems - .filter(s => s.name.toLowerCase().includes(search)) - .map(nav => ( - - } - active={!!isActive(nav?.to as string)} - > - {nav.name} - - ))} - - - - -
-
- ); -}; - -type SidebarHeaderProps = { children?: React.ReactNode }; -export const SidebarHeader = ({ children }: SidebarHeaderProps) => { - return {children}; -}; - -type SidebarFooterProps = { children?: React.ReactNode }; -export const SidebarFooter = ({ children }: SidebarFooterProps) => { - return {children}; -}; diff --git a/web/sdk/react/components/organization/sidebar/sidebar.module.css b/web/sdk/react/components/organization/sidebar/sidebar.module.css deleted file mode 100644 index e99f6170f..000000000 --- a/web/sdk/react/components/organization/sidebar/sidebar.module.css +++ /dev/null @@ -1,22 +0,0 @@ -.sidebarWrapper { - box-sizing: border-box; - border-top-left-radius: var(--rs-radius-6); - border-bottom-left-radius: var(--rs-radius-6); - overflow: hidden; -} - -.scrollArea { - width: 100%; - overflow-y: auto; -} - -.sidebarItemIcon { - display: none; -} - -.sidebarItemGroupContainer { - gap: var(--rs-space-2); -} -.sidebarItemGroup { - padding-left: var(--rs-space-7); -} diff --git a/web/sdk/react/components/organization/styles.module.css b/web/sdk/react/components/organization/styles.module.css deleted file mode 100644 index f56aefbe0..000000000 --- a/web/sdk/react/components/organization/styles.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.header { - margin-bottom: var(--rs-space-9); -} - -.container { - padding: var(--rs-space-9) var(--rs-space-11); - overflow: scroll; -} - -.containerFlex { - flex: 1; - min-height: 0; - display: flex; - flex-direction: column; - overflow: hidden; -} - -.contentWrapper { - flex: 1; - min-height: 0; - overflow: hidden; -} - -.pageWrapper { - width: 100%; - height: 100%; -} - diff --git a/web/sdk/react/components/organization/teams/index.tsx b/web/sdk/react/components/organization/teams/index.tsx deleted file mode 100644 index 36aca38c9..000000000 --- a/web/sdk/react/components/organization/teams/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useNavigate } from '@tanstack/react-router'; -import { TeamsListPage } from '~/react/views/teams'; - -export default function WorkspaceTeams() { - const navigate = useNavigate({ from: '/teams' }); - - return - navigate({ to: '/teams/$teamId', params: { teamId } }) - } - />; -} \ No newline at end of file diff --git a/web/sdk/react/components/organization/teams/team.tsx b/web/sdk/react/components/organization/teams/team.tsx deleted file mode 100644 index 2e6733f43..000000000 --- a/web/sdk/react/components/organization/teams/team.tsx +++ /dev/null @@ -1,16 +0,0 @@ -'use client'; - -import { useNavigate, useParams } from '@tanstack/react-router'; -import { TeamDetailPage } from '~/react/views/teams'; - -export const TeamPage = () => { - const { teamId } = useParams({ from: '/teams/$teamId' }); - const navigate = useNavigate({ from: '/teams/$teamId' }); - - return ( - navigate({ to: '/teams' })} - /> - ); -}; diff --git a/web/sdk/react/components/organization/tokens/index.tsx b/web/sdk/react/components/organization/tokens/index.tsx deleted file mode 100644 index 554c82c3a..000000000 --- a/web/sdk/react/components/organization/tokens/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import { TokensPage } from '~/react/views/tokens'; - -export default function Tokens() { - return ; -} diff --git a/web/sdk/react/components/organization/user/index.tsx b/web/sdk/react/components/organization/user/index.tsx deleted file mode 100644 index 0e386aad6..000000000 --- a/web/sdk/react/components/organization/user/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -'use client'; - -import { ProfilePage } from '~/react/views/profile'; - -export function UserSetting() { - return ; -} diff --git a/web/sdk/react/components/view-container/view-container.tsx b/web/sdk/react/components/view-container/view-container.tsx index 8ab4adbc6..71ee048e4 100644 --- a/web/sdk/react/components/view-container/view-container.tsx +++ b/web/sdk/react/components/view-container/view-container.tsx @@ -1,5 +1,5 @@ import { ComponentProps } from 'react'; -import { Flex } from '@raystack/apsara-v1'; +import { Flex } from '@raystack/apsara'; import styles from './view-container.module.css'; import { cx } from 'class-variance-authority'; diff --git a/web/sdk/react/components/view-header/view-header.tsx b/web/sdk/react/components/view-header/view-header.tsx index f36606c90..8893eecfc 100644 --- a/web/sdk/react/components/view-header/view-header.tsx +++ b/web/sdk/react/components/view-header/view-header.tsx @@ -1,5 +1,5 @@ import { ComponentProps, ReactNode } from 'react'; -import { Flex, Headline, Text } from '@raystack/apsara-v1'; +import { Flex, Headline, Text } from '@raystack/apsara'; export interface ViewHeaderProps extends ComponentProps { title: string; diff --git a/web/sdk/react/components/window/index.tsx b/web/sdk/react/components/window/index.tsx deleted file mode 100644 index 5c206464d..000000000 --- a/web/sdk/react/components/window/index.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Flex, Image, Dialog } from '@raystack/apsara'; -import type React from 'react'; -import { useState } from 'react'; -import closeClose from '~/react/assets/close-close.svg'; -import closeDefault from '~/react/assets/close-default.svg'; -import resizeCollapse from '~/react/assets/resize-collapse.svg'; -import resizeDefault from '~/react/assets/resize-default.svg'; -import resizeExpand from '~/react/assets/resize-expand.svg'; -// @ts-ignore -import styles from './window.module.css'; - -interface WindowProps extends React.HTMLAttributes { - open?: boolean; - onOpenChange?: (open: boolean) => void; - children?: React.ReactNode; -} - -export const Window = ({ - open = false, - onOpenChange, - children, - ...props -}: WindowProps) => { - const [zoom, setZoom] = useState(false); - const [isCloseActive, setCloseActive] = useState(false); - const [isZoomActive, setZoomActive] = useState(false); - - return ( - - -
{children}
-
- - setCloseActive(true)} - onMouseOut={() => setCloseActive(false)} - alt="close-button" - src={ - isCloseActive - ? (closeClose as unknown as string) - : (closeDefault as unknown as string) - } - onClick={() => onOpenChange && onOpenChange(false)} - style={{ cursor: 'pointer' }} - data-test-id="frontier-sdk-window-close-button" - /> - setZoomActive(true)} - onMouseOut={() => setZoomActive(false)} - alt="maximize-toggle-button" - src={ - isZoomActive - ? zoom - ? (resizeCollapse as unknown as string) - : (resizeExpand as unknown as string) - : (resizeDefault as unknown as string) - } - onClick={() => setZoom(!zoom)} - style={{ cursor: 'pointer' }} - data-test-id="frontier-sdk-window-maximize-button" - /> - -
-
-
- ); -}; diff --git a/web/sdk/react/components/window/window.module.css b/web/sdk/react/components/window/window.module.css deleted file mode 100644 index 0497fdd4f..000000000 --- a/web/sdk/react/components/window/window.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.container { - padding: 0; -} - -.dialogContentZoomin { - width: 100vw; - height: 100vh; - max-height: unset; - margin-top: 0; - zindex: 1; -} - -.dialogContentZoomout { - width: 80vw; - height: 80vh; -} - -.overlay { - background-color: rgba(104, 112, 118, 0.50); -} \ No newline at end of file diff --git a/web/sdk/react/contexts/FrontierProvider.tsx b/web/sdk/react/contexts/FrontierProvider.tsx index d588f764f..48ac17c19 100644 --- a/web/sdk/react/contexts/FrontierProvider.tsx +++ b/web/sdk/react/contexts/FrontierProvider.tsx @@ -1,4 +1,4 @@ -import { ThemeProvider, Toast } from '@raystack/apsara-v1'; +import { Theme, Toast } from '@raystack/apsara'; import { FrontierProviderProps } from '../../shared/types'; import { FrontierContextProvider } from './FrontierContext'; import { CustomizationProvider } from './CustomizationContext'; @@ -36,7 +36,7 @@ export const FrontierProvider = (props: FrontierProviderProps) => { config={config} {...options} > - + {children} diff --git a/web/sdk/react/hooks/useSessions.ts b/web/sdk/react/hooks/useSessions.ts index 363c4b94b..640a84477 100644 --- a/web/sdk/react/hooks/useSessions.ts +++ b/web/sdk/react/hooks/useSessions.ts @@ -7,7 +7,7 @@ import { } from '@connectrpc/connect-query'; import { useQueryClient } from '@tanstack/react-query'; import { FrontierServiceQueries } from '@raystack/proton/frontier'; -import { toast } from '@raystack/apsara'; +import { toastManager } from '@raystack/apsara'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { timestampToDayjs } from '../../utils/timestamp'; @@ -86,11 +86,16 @@ export const useSessions = () => { cardinality: 'finite' }) }); - toast.success('Session revoked successfully'); + toastManager.add({ + title: 'Session revoked successfully', + type: 'success' + }); }, onError: (error: any) => { - toast.error('Failed to revoke session', { - description: getErrorMessage(error) + toastManager.add({ + title: 'Failed to revoke session', + description: getErrorMessage(error), + type: 'error' }); } } diff --git a/web/sdk/react/hooks/useSessionsV1.ts b/web/sdk/react/hooks/useSessionsV1.ts deleted file mode 100644 index fe11397d9..000000000 --- a/web/sdk/react/hooks/useSessionsV1.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { useMemo } from 'react'; -import { - useQuery, - useMutation, - createConnectQueryKey, - useTransport -} from '@connectrpc/connect-query'; -import { useQueryClient } from '@tanstack/react-query'; -import { FrontierServiceQueries } from '@raystack/proton/frontier'; -import { toastManager } from '@raystack/apsara-v1'; -import dayjs from 'dayjs'; -import relativeTime from 'dayjs/plugin/relativeTime'; -import { timestampToDayjs } from '../../utils/timestamp'; -import { formatLocation } from '../utils'; - -dayjs.extend(relativeTime); - -// Utility function to format error messages based on status code -const getErrorMessage = (error: unknown): string => { - if (error instanceof Error && 'status' in error && error.status === 500) { - return 'Something went wrong'; - } - if (error instanceof Error) { - return error.message; - } - return 'Something went wrong'; -}; - -export const formatDeviceDisplay = ( - browser?: string, - operatingSystem?: string -): string => { - const browserName = browser || 'Unknown'; - const osName = operatingSystem || 'Unknown'; - return browserName === 'Unknown' && osName === 'Unknown' - ? 'Unknown browser and OS' - : `${browserName} on ${osName}`; -}; - -export const useSessions = () => { - const queryClient = useQueryClient(); - const transport = useTransport(); - - const { - data: sessionsData, - isLoading, - error - } = useQuery(FrontierServiceQueries.listSessions, {}); - - const formatLastActive = (updatedAt?: any) => { - const d = timestampToDayjs(updatedAt); - return d ? d.fromNow() : 'Unknown'; - }; - - const sessions = useMemo( - () => - (sessionsData?.sessions || []) - .map((session: any) => ({ - id: session.id || '', - browser: session.metadata?.browser || 'Unknown', - operatingSystem: session.metadata?.operatingSystem || 'Unknown', - ipAddress: session.metadata?.ipAddress || 'Unknown', - location: formatLocation(session.metadata?.location), - lastActive: formatLastActive(session.updatedAt), - isCurrent: session.isCurrentSession || false - })) - .sort((a, b) => { - // Current session first, then by last active (most recent first) - if (a.isCurrent && !b.isCurrent) return -1; - if (!a.isCurrent && b.isCurrent) return 1; - return 0; // Keep original order for non-current sessions - }), - [sessionsData?.sessions] - ); - - const { mutate: revokeSession, isPending: isRevokingSession } = useMutation( - FrontierServiceQueries.revokeSession, - { - onSuccess: () => { - // Invalidate and refetch the sessions list - queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listSessions, - transport, - input: {}, - cardinality: 'finite' - }) - }); - toastManager.add({ - title: 'Session revoked successfully', - type: 'success' - }); - }, - onError: (error: any) => { - toastManager.add({ - title: 'Failed to revoke session', - description: getErrorMessage(error), - type: 'error' - }); - } - } - ); - - const handleRevokeSession = (sessionId: string, options?: any) => { - revokeSession({ sessionId }, options); - }; - - return { - sessions, - isLoading, - error: error?.message || null, - refetch: () => {}, - revokeSession: handleRevokeSession, - isRevokingSession - }; -}; diff --git a/web/sdk/react/hooks/useTokens.ts b/web/sdk/react/hooks/useTokens.ts index 5a30b0e24..cfbdf6aeb 100644 --- a/web/sdk/react/hooks/useTokens.ts +++ b/web/sdk/react/hooks/useTokens.ts @@ -3,7 +3,7 @@ import { useQuery } from '@connectrpc/connect-query'; import { create } from '@bufbuild/protobuf'; import { FrontierServiceQueries, GetBillingBalanceRequestSchema } from '@raystack/proton/frontier'; import { useFrontier } from '../contexts/FrontierContext'; -import { toast } from '@raystack/apsara'; +import { toastManager } from '@raystack/apsara'; interface UseTokensReturn { tokenBalance: bigint; @@ -34,7 +34,10 @@ export const useTokens = (): UseTokensReturn => { useEffect(() => { if (error) { console.error(error); - toast.error('Unable to fetch balance'); + toastManager.add({ + title: 'Unable to fetch balance', + type: 'error' + }); } }, [error]); diff --git a/web/sdk/react/hooks/useTokensV1.ts b/web/sdk/react/hooks/useTokensV1.ts deleted file mode 100644 index f1f3b263f..000000000 --- a/web/sdk/react/hooks/useTokensV1.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { useMemo, useEffect } from 'react'; -import { useQuery } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { FrontierServiceQueries, GetBillingBalanceRequestSchema } from '@raystack/proton/frontier'; -import { useFrontier } from '../contexts/FrontierContext'; -import { toastManager } from '@raystack/apsara-v1'; - -interface UseTokensReturn { - tokenBalance: bigint; - isTokensLoading: boolean; - fetchTokenBalance: () => Promise; -} - -export const useTokens = (): UseTokensReturn => { - const { billingAccount } = useFrontier(); - - const { - data, - isLoading: isTokensLoading, - error, - refetch - } = useQuery( - FrontierServiceQueries.getBillingBalance, - create(GetBillingBalanceRequestSchema, { - id: billingAccount?.id ?? '' - }), - { - enabled: !!billingAccount?.id, - retry: false - } - ); - - // Handle errors - useEffect(() => { - if (error) { - console.error(error); - toastManager.add({ - title: 'Unable to fetch balance', - type: 'error' - }); - } - }, [error]); - - const tokenBalance = useMemo( - () => BigInt(data?.balance?.amount || '0'), - [data?.balance?.amount] - ); - - return { - tokenBalance, - isTokensLoading, - fetchTokenBalance: refetch - }; -}; diff --git a/web/sdk/react/index.ts b/web/sdk/react/index.ts index cff68faed..787cebd89 100644 --- a/web/sdk/react/index.ts +++ b/web/sdk/react/index.ts @@ -1,17 +1,36 @@ import '@raystack/apsara/style.css'; +import '@raystack/apsara/normalize.css'; -export { AvatarUpload } from './components/avatar-upload'; -export { Container } from './components/Container'; -export { Header } from './components/Header'; -export { MagicLink } from './components/onboarding/magiclink'; -export { MagicLinkVerify } from './components/onboarding/magiclink-verify'; -export { SignIn } from './components/onboarding/signin'; -export { SignUp } from './components/onboarding/signup'; -export { Updates } from './components/onboarding/updates'; -export { Subscribe } from './components/onboarding/subscribe'; -export { CreateOrganization } from './components/organization/create'; -export { OrganizationProfile } from './components/organization/profile'; -export { Window } from './components/window'; +export { ImageUpload } from './components/image-upload'; +export { ViewContainer } from './components/view-container'; +export { ViewHeader } from './components/view-header'; +export { AuthContainer } from './components/auth-container'; +export { AuthHeader } from './components/auth-header'; + +export { SignInView } from './views/auth/sign-in'; +export { SignUpView } from './views/auth/sign-up'; +export { MagicLinkView } from './views/auth/magic-link'; +export { MagicLinkVerifyView } from './views/auth/magic-link-verify'; +export { SubscribeView } from './views/auth/subscribe'; +export { UpdatesView } from './views/auth/updates'; + +export { GeneralView } from './views/general'; +export { PreferencesView, PreferenceRow } from './views/preferences'; +export { ProfileView } from './views/profile'; +export { SessionsView } from './views/sessions'; +export { MembersView } from './views/members'; +export { SecurityView } from './views/security'; +export { ProjectsView, ProjectDetailsView } from './views/projects'; +export { BillingView } from './views/billing'; +export { TokensView } from './views/tokens'; +export { TeamsView, TeamDetailsView } from './views/teams'; +export { + ServiceAccountsView, + ServiceAccountDetailsView +} from './views/service-accounts'; +export { PlansView } from './views/plans'; +export { PatsView, PATDetailsView } from './views/pat'; +export { CreateOrganizationView } from './views/create-organization'; export { useFrontier } from './contexts/FrontierContext'; export { FrontierProvider, queryClient } from './contexts/FrontierProvider'; @@ -22,8 +41,6 @@ export { useTokens } from './hooks/useTokens'; export { useBillingPermission } from './hooks/useBillingPermission'; export { useConnectQueryPolling } from './hooks/useConnectQueryPolling'; export { usePreferences } from './hooks/usePreferences'; -export { Layout } from './components/Layout'; -export { PageHeader } from './components/common/page-header'; export type { FrontierClientOptions, diff --git a/web/sdk/react/utils/transform-query.ts b/web/sdk/react/utils/transform-query.ts index 99fb51763..3c94da41b 100644 --- a/web/sdk/react/utils/transform-query.ts +++ b/web/sdk/react/utils/transform-query.ts @@ -1,4 +1,4 @@ -import type { DataTableQuery, DataTableSort } from '@raystack/apsara-v1'; +import type { DataTableQuery, DataTableSort } from '@raystack/apsara'; import type { RQLRequest, RQLFilter, RQLSort } from '@raystack/proton/frontier'; import { RQLRequestSchema, diff --git a/web/sdk/react/views-new/billing/index.ts b/web/sdk/react/views-new/billing/index.ts deleted file mode 100644 index edd0f7437..000000000 --- a/web/sdk/react/views-new/billing/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { BillingView } from './billing-view'; -export type { BillingViewProps } from './billing-view'; diff --git a/web/sdk/react/views-new/general/index.ts b/web/sdk/react/views-new/general/index.ts deleted file mode 100644 index d2d160404..000000000 --- a/web/sdk/react/views-new/general/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { GeneralView } from './general-view'; -export type { GeneralViewProps } from './general-view'; diff --git a/web/sdk/react/views-new/members/index.ts b/web/sdk/react/views-new/members/index.ts deleted file mode 100644 index 5ff94716e..000000000 --- a/web/sdk/react/views-new/members/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { MembersView } from './members-view'; -export type { MembersViewProps } from './members-view'; diff --git a/web/sdk/react/views-new/plans/helpers/index.ts b/web/sdk/react/views-new/plans/helpers/index.ts deleted file mode 100644 index de901797a..000000000 --- a/web/sdk/react/views-new/plans/helpers/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - IntervalKeys, - PlanIntervalPricing -} from '~/src/types'; -import { getPlanPrice, makePlanSlug } from '~/react/utils'; -import { Plan } from '@raystack/proton/frontier'; - -export function groupPlansPricingByInterval(plans: Plan[]) { - const plansMap: Record = {}; - plans.forEach(plan => { - const metaData = (plan?.metadata as Record) || {}; - const slug = metaData?.plan_group_id || makePlanSlug(plan); - plansMap[slug] = plansMap[slug] || { - slug: slug, - title: plan.title, - description: plan?.description, - weightage: 0, - intervals: {}, - features: {} - }; - const planInterval = (plan?.interval || '') as IntervalKeys; - const productPrices = getPlanPrice(plan); - - const planMetadata = (plan?.metadata as Record) || {}; - plansMap[slug].intervals[planInterval] = { - planId: plan?.id || '', - planName: plan?.name || '', - interval: planInterval, - weightage: planMetadata?.weightage ? Number(planMetadata?.weightage) : 0, - productNames: [], - trialDays: plan?.trialDays ? String(plan.trialDays) : '', - features: {}, - ...productPrices - }; - - plan?.products?.forEach(product => { - plansMap[slug].intervals[planInterval].productNames = [ - ...plansMap[slug].intervals[planInterval].productNames, - product.name || '' - ]; - product.features?.forEach(feature => { - plansMap[slug].intervals[planInterval].features[feature?.title || ''] = - feature; - }); - }); - - plansMap[slug].weightage = Object.values(plansMap[slug].intervals).reduce( - (acc, data) => acc + data.weightage, - 0 - ); - }); - - return Object.values(plansMap); -} diff --git a/web/sdk/react/views-new/plans/index.ts b/web/sdk/react/views-new/plans/index.ts deleted file mode 100644 index 19ac803f7..000000000 --- a/web/sdk/react/views-new/plans/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { PlansView } from './plans-view'; diff --git a/web/sdk/react/views-new/preferences/index.ts b/web/sdk/react/views-new/preferences/index.ts deleted file mode 100644 index b275ef776..000000000 --- a/web/sdk/react/views-new/preferences/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { PreferencesView } from './preferences-view'; -export { PreferenceRow } from './components/preference-row'; diff --git a/web/sdk/react/views-new/profile/index.ts b/web/sdk/react/views-new/profile/index.ts deleted file mode 100644 index b58061c0d..000000000 --- a/web/sdk/react/views-new/profile/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ProfileView } from './profile-view'; diff --git a/web/sdk/react/views-new/projects/index.ts b/web/sdk/react/views-new/projects/index.ts deleted file mode 100644 index 4c506aea1..000000000 --- a/web/sdk/react/views-new/projects/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { ProjectsView } from './projects-view'; -export { ProjectDetailsView } from './project-details-view'; -export type { ProjectDetailsViewProps } from './project-details-view'; diff --git a/web/sdk/react/views-new/security/index.ts b/web/sdk/react/views-new/security/index.ts deleted file mode 100644 index e823b933a..000000000 --- a/web/sdk/react/views-new/security/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { SecurityView } from './security-view'; -export type { SecurityViewProps } from './security-view'; diff --git a/web/sdk/react/views-new/sessions/index.ts b/web/sdk/react/views-new/sessions/index.ts deleted file mode 100644 index 79c2438f0..000000000 --- a/web/sdk/react/views-new/sessions/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { SessionsView } from './sessions-view'; -export type { SessionsViewProps } from './sessions-view'; diff --git a/web/sdk/react/views-new/teams/index.ts b/web/sdk/react/views-new/teams/index.ts deleted file mode 100644 index ccd5a7252..000000000 --- a/web/sdk/react/views-new/teams/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { TeamsView } from './teams-view'; -export { TeamDetailsView } from './team-details-view'; -export type { TeamDetailsViewProps } from './team-details-view'; diff --git a/web/sdk/react/views-new/tokens/index.ts b/web/sdk/react/views-new/tokens/index.ts deleted file mode 100644 index ab80762dc..000000000 --- a/web/sdk/react/views-new/tokens/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TokensView } from './tokens-view'; diff --git a/web/sdk/react/views/api-keys/details/add-service-user-token.tsx b/web/sdk/react/views/api-keys/details/add-service-user-token.tsx deleted file mode 100644 index 78aecfde6..000000000 --- a/web/sdk/react/views/api-keys/details/add-service-user-token.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { useForm } from 'react-hook-form'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useCallback } from 'react'; -import { Flex, toast, Button, InputField } from '@raystack/apsara'; -import styles from './service-user.module.css'; -import { useMutation } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { - FrontierServiceQueries, - CreateServiceUserTokenRequestSchema, - type ServiceUserToken -} from '@raystack/proton/frontier'; - -const serviceAccountSchema = yup - .object({ - title: yup.string().required('Name is a required field') - }) - .required(); - -type FormData = yup.InferType; - -export default function AddServiceUserToken({ - serviceUserId, - onAddToken = () => {} -}: { - serviceUserId: string; - onAddToken: (token: ServiceUserToken) => void; -}) { - const { activeOrganization } = useFrontier(); - const { - register, - handleSubmit, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(serviceAccountSchema) - }); - - const orgId = activeOrganization?.id || ''; - - const { mutateAsync: createServiceUserToken } = useMutation( - FrontierServiceQueries.createServiceUserToken - ); - - const onSubmit = useCallback( - async (data: FormData) => { - try { - const response = await createServiceUserToken( - create(CreateServiceUserTokenRequestSchema, { - orgId, - id: serviceUserId, - title: data.title - }) - ); - if (response.token) { - onAddToken(response.token); - toast.success('Api key created'); - } - } catch (error: unknown) { - toast.error('Something went wrong', { - description: error instanceof Error ? error.message : 'Unknown error' - }); - } - }, - [createServiceUserToken, onAddToken, serviceUserId, orgId] - ); - - return ( -
- - - - - - -
- ); -} diff --git a/web/sdk/react/views/api-keys/details/delete-service-user-key-dialog.tsx b/web/sdk/react/views/api-keys/details/delete-service-user-key-dialog.tsx deleted file mode 100644 index 7e11ac88a..000000000 --- a/web/sdk/react/views/api-keys/details/delete-service-user-key-dialog.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Button, Flex, Text, toast, Image, Dialog } from '@raystack/apsara'; -import cross from '~/react/assets/cross.svg'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import styles from './service-user.module.css'; -import { useTerminology } from '~/react/hooks/useTerminology'; -import { useMutation } from '@connectrpc/connect-query'; -import { - FrontierServiceQueries, - DeleteServiceUserTokenRequestSchema -} from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; -import { useServiceUserTokens } from '../hooks/useServiceUserTokens'; - -export interface DeleteServiceUserKeyDialogProps { - open: boolean; - onOpenChange?: (value: boolean) => void; - serviceUserId: string; - tokenId: string; -} - -export const DeleteServiceUserKeyDialog = ({ - open, - onOpenChange, - serviceUserId, - tokenId -}: DeleteServiceUserKeyDialogProps) => { - const { activeOrganization } = useFrontier(); - - const orgId = activeOrganization?.id || ''; - - const { removeToken } = useServiceUserTokens({ - id: serviceUserId, - orgId, - enableFetch: false - }); - - const { mutateAsync: deleteServiceUserToken, isPending } = useMutation( - FrontierServiceQueries.deleteServiceUserToken - ); - - const handleClose = () => onOpenChange?.(false); - - async function onDeleteClick() { - try { - await deleteServiceUserToken( - create(DeleteServiceUserTokenRequestSchema, { - id: serviceUserId, - tokenId, - orgId - }) - ); - - // Remove token from cache - removeToken(tokenId); - - handleClose(); - toast.success('Service account key revoked'); - } catch (error: unknown) { - toast.error('Unable to revoke service account key', { - description: error instanceof Error ? error.message : 'Unknown error' - }); - } - } - - const t = useTerminology(); - - return ( - - - - - - Revoke API Key - - - cross - - - - - - - This is an irreversible action doing this might lead to - discontinuation of access to the {t.appName()} features. Do you - wish to proceed? - - - - - - - - - - - - - ); -}; diff --git a/web/sdk/react/views/api-keys/details/index.ts b/web/sdk/react/views/api-keys/details/index.ts deleted file mode 100644 index 00018d019..000000000 --- a/web/sdk/react/views/api-keys/details/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { default as ServiceUserDetailPage } from './service-user-detail-page'; -export type { ServiceUserDetailPageProps } from './service-user-detail-page'; - -export { DeleteServiceUserKeyDialog } from './delete-service-user-key-dialog'; -export type { DeleteServiceUserKeyDialogProps } from './delete-service-user-key-dialog'; - -export { default as ManageServiceUserProjectsDialog } from './manage-service-user-projects-dialog'; -export type { ManageServiceUserProjectsDialogProps } from './manage-service-user-projects-dialog'; diff --git a/web/sdk/react/views/api-keys/details/manage-service-user-projects-dialog.tsx b/web/sdk/react/views/api-keys/details/manage-service-user-projects-dialog.tsx deleted file mode 100644 index ef43727be..000000000 --- a/web/sdk/react/views/api-keys/details/manage-service-user-projects-dialog.tsx +++ /dev/null @@ -1,283 +0,0 @@ -import { - Checkbox, - Flex, - Spinner, - Text, - toast, - Image, - Dialog, - DataTable, - type DataTableColumnDef -} from '@raystack/apsara'; -import { useCallback, useState, useEffect, useMemo } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { PERMISSIONS } from '~/utils'; -import cross from '~/react/assets/cross.svg'; -import styles from './service-user.module.css'; -import { useQuery, useMutation } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { - FrontierServiceQueries, - ListServiceUserProjectsRequestSchema, - ListOrganizationProjectsRequestSchema, - ListRolesRequestSchema, - SetProjectMemberRoleRequestSchema, - RemoveProjectMemberRequestSchema, - Project -} from '@raystack/proton/frontier'; -import { orderBy } from 'lodash'; - -type ProjectAccessMap = Record; - -const getColumns = ({ - permMap, - onChange -}: { - permMap: ProjectAccessMap; - onChange: (projectId: string, value: boolean) => void; -}): DataTableColumnDef[] => { - return [ - { - header: '', - id: 'checkbox', - accessorKey: 'id', - enableSorting: false, - styles: { - cell: { - width: 'var(--rs-space-2)' - } - }, - cell: ({ getValue }) => { - const projectId = getValue() as string; - const { value, isLoading } = permMap[projectId] || {}; - return ( - - {isLoading ? ( - - ) : ( - onChange(projectId, v === true)} - /> - )} - - ); - } - }, - { - header: 'Project Name', - accessorKey: 'title', - cell: ({ getValue }) => { - const value = getValue() as string; - return ( - - {value} - - ); - } - }, - { - header: 'Access', - accessorKey: 'id', - enableSorting: false, - cell: () => ( - - Member - - ) - } - ]; -}; - -export interface ManageServiceUserProjectsDialogProps { - open: boolean; - onOpenChange?: (value: boolean) => void; - serviceUserId: string; -} - -export default function ManageServiceUserProjectsDialog({ - open, - onOpenChange, - serviceUserId -}: ManageServiceUserProjectsDialogProps) { - const { activeOrganization: organization } = useFrontier(); - - const [addedProjectsMap, setAddedProjectsMap] = useState( - {} - ); - - const handleClose = () => onOpenChange?.(false); - - const orgId = organization?.id || ''; - - const { data: projectsData, isLoading: isProjectsLoading } = useQuery( - FrontierServiceQueries.listOrganizationProjects, - create(ListOrganizationProjectsRequestSchema, { - id: orgId, - state: '', - withMemberCount: false - }), - { - enabled: Boolean(orgId) && open - } - ); - - const projects = useMemo(() => { - const list = projectsData?.projects ?? []; - return orderBy(list, ['title'], ['asc']); - }, [projectsData]); - - const { data: addedProjectsData, isLoading: isAddedProjectsLoading } = - useQuery( - FrontierServiceQueries.listServiceUserProjects, - create(ListServiceUserProjectsRequestSchema, { - id: serviceUserId, - orgId, - withPermissions: [] - }), - { - enabled: Boolean(serviceUserId) && Boolean(orgId) && open - } - ); - - const addedProjects = useMemo( - () => addedProjectsData?.projects ?? [], - [addedProjectsData] - ); - - // Initialize addedProjectsMap from query data - useEffect(() => { - const permMap = addedProjects.reduce((acc, proj) => { - acc[proj?.id || ''] = { value: true, isLoading: false }; - return acc; - }, {} as ProjectAccessMap); - setAddedProjectsMap(permMap); - }, [addedProjects]); - - const { data: rolesData } = useQuery( - FrontierServiceQueries.listRoles, - create(ListRolesRequestSchema, { - state: 'enabled', - scopes: [PERMISSIONS.ProjectNamespace] - }), - { enabled: open } - ); - - const ownerRoleId = useMemo( - () => rolesData?.roles?.find(r => r.name === PERMISSIONS.RoleProjectOwner)?.id ?? '', - [rolesData] - ); - - const { mutateAsync: setProjectMemberRole } = useMutation( - FrontierServiceQueries.setProjectMemberRole - ); - - const { mutateAsync: removeProjectMember } = useMutation( - FrontierServiceQueries.removeProjectMember - ); - - const onAccessChange = useCallback( - async (projectId: string, value: boolean) => { - try { - setAddedProjectsMap(prev => ({ - ...prev, - [projectId]: { ...prev[projectId], isLoading: true } - })); - - if (value) { - if (!ownerRoleId) { - toast.error('Project owner role not found'); - return; - } - await setProjectMemberRole( - create(SetProjectMemberRoleRequestSchema, { - projectId, - principalId: serviceUserId, - principalType: PERMISSIONS.ServiceUserPrincipal, - roleId: ownerRoleId - }) - ); - setAddedProjectsMap(prev => ({ - ...prev, - [projectId]: { value: true, isLoading: false } - })); - } else { - await removeProjectMember( - create(RemoveProjectMemberRequestSchema, { - projectId, - principalId: serviceUserId, - principalType: PERMISSIONS.ServiceUserPrincipal - }) - ); - setAddedProjectsMap(prev => ({ - ...prev, - [projectId]: { value: false, isLoading: false } - })); - } - } catch (error: unknown) { - console.error(error); - toast.error('unable to update project access'); - setAddedProjectsMap(prev => ({ - ...prev, - [projectId]: { ...prev[projectId], isLoading: false } - })); - } - }, - [serviceUserId, ownerRoleId, setProjectMemberRole, removeProjectMember] - ); - - const columns = getColumns({ - permMap: addedProjectsMap, - onChange: onAccessChange - }); - - const data = projects || []; - - const isLoading = isProjectsLoading || isAddedProjectsLoading; - - return ( - - - - - - Manage Project Access - - - cross - - - - - - - Note: Select projects to give access to the service user. - - - - - - - - - ); -} diff --git a/web/sdk/react/views/api-keys/details/service-user-detail-page.tsx b/web/sdk/react/views/api-keys/details/service-user-detail-page.tsx deleted file mode 100644 index 7e07c9b58..000000000 --- a/web/sdk/react/views/api-keys/details/service-user-detail-page.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { useState } from 'react'; -import { Button, Flex, Text, Skeleton, Image } from '@raystack/apsara'; -import { PageHeader } from '~/react/components/common/page-header'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import AddServiceUserToken from './add-service-user-token'; -import { CheckCircledIcon, CopyIcon } from '@radix-ui/react-icons'; -import { useCopyToClipboard } from '~/react/hooks/useCopyToClipboard'; -import { useTerminology } from '~/react/hooks/useTerminology'; -import { useQuery } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { - FrontierServiceQueries, - GetServiceUserRequestSchema, - type ServiceUserToken -} from '@raystack/proton/frontier'; -import { useServiceUserTokens } from '../hooks/useServiceUserTokens'; -import ManageServiceUserProjectsDialog from './manage-service-user-projects-dialog'; -import { DeleteServiceUserKeyDialog } from './delete-service-user-key-dialog'; - -import backIcon from '~/react/assets/chevron-left.svg'; -import sharedStyles from '../../../components/organization/styles.module.css'; -import styles from './service-user.module.css'; - -const Headings = ({ - isLoading, - name, - onManageAccessClick -}: { - isLoading: boolean; - name: string; - onManageAccessClick?: () => void; -}) => { - const t = useTerminology(); - - return ( - - {isLoading ? ( - - ) : ( - - {name} - - - )} - {isLoading ? ( - - ) : ( - - Create API key for accessing {t.appName()} and its features - - )} - - ); -}; - -const ServiceUserTokenItem = ({ - token, - isLoading, - onRevokeClick -}: { - token: ServiceUserToken; - isLoading: boolean; - onRevokeClick?: (tokenId: string) => void; -}) => { - const [isCopied, setIsCopied] = useState(false); - const { copy } = useCopyToClipboard(); - - const encodedToken = 'Basic ' + btoa(`${token?.id}:${token?.token}`); - - async function onCopy() { - const res = await copy(encodedToken); - if (res) { - setIsCopied(true); - setTimeout(() => { - setIsCopied(false); - }, 1000); - } - } - - return ( - - - {isLoading ? ( - <> - - - - ) : ( - <> - - {token?.title} - - - - )} - - {token?.token ? ( - - - Note: Please save your key securely, it cannot be recovered after - leaving this page - - - - {encodedToken} - - {isCopied ? ( - - ) : ( - - )} - - - ) : null} - - ); -}; - -const SerivceUserTokenList = ({ - isLoading, - tokens, - onRevokeClick -}: { - isLoading: boolean; - tokens: ServiceUserToken[]; - onRevokeClick?: (tokenId: string) => void; -}) => { - const tokenList = isLoading - ? [ - ...new Array(3).map( - (_, i) => ({ id: i.toString() } as ServiceUserToken) - ) - ] - : tokens; - - return ( - - {tokenList.map(token => ( - - ))} - - ); -}; - -export interface ServiceUserDetailPageProps { - serviceUserId: string; - onBack?: () => void; - enableTokensFetch?: boolean; -} - -export default function ServiceUserDetailPage({ - serviceUserId, - onBack, - enableTokensFetch = true -}: ServiceUserDetailPageProps) { - const { activeOrganization } = useFrontier(); - const orgId = activeOrganization?.id || ''; - - const { data: serviceUser, isLoading: isServiceUserLoading } = useQuery( - FrontierServiceQueries.getServiceUser, - create(GetServiceUserRequestSchema, { - id: serviceUserId, - orgId - }), - { - enabled: Boolean(serviceUserId) && Boolean(orgId), - select: data => data?.serviceuser - } - ); - - const { - tokens: serviceUserTokens, - isLoading: isServiceUserTokensLoading, - addToken: onAddToken - } = useServiceUserTokens({ - id: serviceUserId, - orgId, - enableFetch: enableTokensFetch - }); - - const isLoading = isServiceUserLoading || isServiceUserTokensLoading; - - const [showProjectsDialog, setShowProjectsDialog] = useState(false); - - const [deleteKeyState, setDeleteKeyState] = useState({ - open: false, - tokenId: '' - }); - - const handleDeleteKeyOpenChange = (value: boolean) => { - if (!value) { - setDeleteKeyState({ open: false, tokenId: '' }); - } else { - setDeleteKeyState(prev => ({ ...prev, open: value })); - } - }; - - const handleRevokeClick = (tokenId: string) => { - setDeleteKeyState({ open: true, tokenId }); - }; - - return ( - - - - - back-icon - - - - - setShowProjectsDialog(true)} - /> - - - - - - - - ); -} diff --git a/web/sdk/react/views/api-keys/details/service-user.module.css b/web/sdk/react/views/api-keys/details/service-user.module.css deleted file mode 100644 index fa176b61d..000000000 --- a/web/sdk/react/views/api-keys/details/service-user.module.css +++ /dev/null @@ -1,93 +0,0 @@ -.flex1 { - flex: 1; -} - -.content { - width: 100%; - padding: var(--rs-space-9) var(--rs-space-11); -} - -.serviceKeyList { - overflow: auto; - height: calc(70vh - 180px); -} - -.serviceKeyItem { - padding: var(--rs-space-5); - border: 1px solid var(--rs-color-border-base-primary); -} - -.serviceKeyItem + .serviceKeyItem { - border-top: none; -} - -.serviceKeyItem:first-of-type { - border-top-left-radius: var(--rs-radius-2); - border-top-right-radius: var(--rs-radius-2); -} - -.serviceKeyItem:last-of-type { - border-bottom-left-radius: var(--rs-radius-2); - border-bottom-right-radius: var(--rs-radius-2); -} - -.serviceKeyItemTitle { - overflow-wrap: break-word; - word-break: break-word; -} - -.serviceKeyItemLoaderBtn { - display: flex; - justify-content: end; - flex: 1; - width: 100px; -} - -.addKeyInputWrapper { - width: 100%; - position: relative; - align-items: start; -} - -.addKeyInputError { - position: absolute; - top: 100%; -} - -.tokenBox { - padding: var(--rs-space-3) var(--rs-space-4); - border-radius: var(--rs-radius-2); - border: 1px solid var(--rs-color-border-base-primary); - background: var(--rs-color-background-base-primary-hover); -} - -.tokenText { - max-width: 90%; - word-break: break-all; -} - -.addDialogContent { - padding: 0; - max-width: 400px; - width: 100%; -} - -.overlay { - background-color: rgba(104, 112, 118, 0.5); -} - -.manageProjectDialogWrapper { - max-height: calc(80vh - var(--rs-space-17)); - overflow: auto; -} - -.manageProjectDialogContent { - height: 80vh; - width: 70%; - padding: 0; -} - -.tableRoot { - height: 100%; - overflow: auto; -} diff --git a/web/sdk/react/views/api-keys/hooks/useServiceUserTokens.ts b/web/sdk/react/views/api-keys/hooks/useServiceUserTokens.ts deleted file mode 100644 index de1d16c05..000000000 --- a/web/sdk/react/views/api-keys/hooks/useServiceUserTokens.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - useQuery, - createConnectQueryKey, - useTransport -} from '@connectrpc/connect-query'; -import { useMemo } from 'react'; -import { useQueryClient } from '@tanstack/react-query'; -import { create } from '@bufbuild/protobuf'; -import { - FrontierServiceQueries, - ListServiceUserTokensRequestSchema, - ListServiceUserTokensResponseSchema, - type ServiceUserToken -} from '@raystack/proton/frontier'; - -interface UseServiceUserTokensOptions { - id: string; - orgId: string; - enableFetch?: boolean; -} - -export const useServiceUserTokens = ({ - id, - orgId, - enableFetch -}: UseServiceUserTokensOptions) => { - const queryClient = useQueryClient(); - const transport = useTransport(); - - const { data: tokensData, isLoading } = useQuery( - FrontierServiceQueries.listServiceUserTokens, - create(ListServiceUserTokensRequestSchema, { - id, - orgId - }), - { - enabled: Boolean(id) && Boolean(orgId) && Boolean(enableFetch) - } - ); - - const tokens = useMemo(() => tokensData?.tokens ?? [], [tokensData]); - - const getQueryKey = () => { - return createConnectQueryKey({ - schema: FrontierServiceQueries.listServiceUserTokens, - transport, - input: create(ListServiceUserTokensRequestSchema, { - id, - orgId - }), - cardinality: 'finite' - }); - }; - - const addToken = (token: ServiceUserToken) => { - const queryKey = getQueryKey(); - const currentData = queryClient.getQueryData(queryKey); - const existingTokens = currentData?.tokens ?? []; - const filteredTokens = existingTokens.filter(t => t !== undefined); - queryClient.setQueryData( - queryKey, - create(ListServiceUserTokensResponseSchema, { - tokens: [token, ...filteredTokens] - }) - ); - }; - - const removeToken = (tokenId: string) => { - const queryKey = getQueryKey(); - const currentData = queryClient.getQueryData(queryKey); - const existingTokens = currentData?.tokens ?? []; - const filteredTokens = existingTokens.filter( - t => t?.id !== tokenId && t !== undefined - ); - queryClient.setQueryData( - queryKey, - create(ListServiceUserTokensResponseSchema, { - tokens: filteredTokens - }) - ); - }; - - return { - tokens, - isLoading, - addToken, - removeToken - }; -}; diff --git a/web/sdk/react/views/api-keys/index.ts b/web/sdk/react/views/api-keys/index.ts deleted file mode 100644 index c8063a26c..000000000 --- a/web/sdk/react/views/api-keys/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './list'; -export * from './details'; diff --git a/web/sdk/react/views/api-keys/list/add-service-account-dialog.tsx b/web/sdk/react/views/api-keys/list/add-service-account-dialog.tsx deleted file mode 100644 index e18f3746b..000000000 --- a/web/sdk/react/views/api-keys/list/add-service-account-dialog.tsx +++ /dev/null @@ -1,317 +0,0 @@ -import { - Button, - Flex, - Text, - toast, - Image, - Skeleton, - Dialog, - InputField, - Select, - Label -} from '@raystack/apsara'; -import { Controller, useForm } from 'react-hook-form'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { useCallback, useMemo } from 'react'; -import { orderBy } from 'lodash'; -import { - FrontierServiceQueries, - CreateServiceUserRequestSchema, - SetProjectMemberRoleRequestSchema, - CreateServiceUserTokenRequestSchema, - ListOrganizationServiceUsersRequestSchema, - ListOrganizationProjectsRequestSchema, - ListRolesRequestSchema, - ListServiceUserTokensRequestSchema, - ListServiceUserTokensResponseSchema, - ServiceUserRequestBodySchema -} from '@raystack/proton/frontier'; -import { PERMISSIONS } from '~/utils'; -import { useQueryClient } from '@tanstack/react-query'; -import { - useMutation, - useQuery, - createConnectQueryKey, - useTransport -} from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import cross from '~/react/assets/cross.svg'; -import styles from './api-keys.module.css'; -import { handleSelectValueChange } from '~/react/utils'; -import { useTerminology } from '~/react/hooks/useTerminology'; - -const DEFAULT_KEY_NAME = 'Initial Generated Key'; - -const serviceAccountSchema = yup - .object({ - title: yup.string().required('Name is a required field'), - project_id: yup.string().required('Project is a required field') - }) - .required(); - -type FormData = yup.InferType; - -export interface AddServiceAccountDialogProps { - open: boolean; - onOpenChange?: (value: boolean) => void; - onCreated?: (serviceUserId: string) => void; -} - -export const AddServiceAccountDialog = ({ - open, - onOpenChange, - onCreated -}: AddServiceAccountDialogProps) => { - const { activeOrganization: organization } = useFrontier(); - const t = useTerminology(); - const queryClient = useQueryClient(); - const transport = useTransport(); - - const handleClose = () => onOpenChange?.(false); - - const { - register, - control, - handleSubmit, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(serviceAccountSchema) - }); - - const orgId = organization?.id || ''; - - const { data: projectsData, isLoading: isProjectsLoading } = useQuery( - FrontierServiceQueries.listOrganizationProjects, - create(ListOrganizationProjectsRequestSchema, { - id: orgId, - state: '', - withMemberCount: false - }), - { - enabled: Boolean(orgId) && open - } - ); - - const projects = useMemo(() => { - const list = projectsData?.projects ?? []; - return orderBy(list, ['title'], ['asc']); - }, [projectsData]); - - const { data: rolesData } = useQuery( - FrontierServiceQueries.listRoles, - create(ListRolesRequestSchema, { - state: 'enabled', - scopes: [PERMISSIONS.ProjectNamespace] - }), - { enabled: open } - ); - - const ownerRoleId = useMemo( - () => rolesData?.roles?.find(r => r.name === PERMISSIONS.RoleProjectOwner)?.id ?? '', - [rolesData] - ); - - const { mutateAsync: createServiceUser } = useMutation( - FrontierServiceQueries.createServiceUser - ); - - const { mutateAsync: setProjectMemberRole } = useMutation( - FrontierServiceQueries.setProjectMemberRole - ); - - const { mutateAsync: createServiceUserToken } = useMutation( - FrontierServiceQueries.createServiceUserToken - ); - - const onSubmit = useCallback( - async (data: FormData) => { - if (!orgId) return; - if (!ownerRoleId) { - toast.error('Project owner role not found'); - return; - } - - try { - const serviceUserResponse = await createServiceUser( - create(CreateServiceUserRequestSchema, { - orgId, - body: create(ServiceUserRequestBodySchema, { - title: data.title - }) - }) - ); - - const serviceUserId = serviceUserResponse.serviceuser?.id; - if (!serviceUserId) return; - await setProjectMemberRole( - create(SetProjectMemberRoleRequestSchema, { - projectId: data.project_id, - principalId: serviceUserId, - principalType: PERMISSIONS.ServiceUserPrincipal, - roleId: ownerRoleId - }) - ); - - const tokenResponse = await createServiceUserToken( - create(CreateServiceUserTokenRequestSchema, { - orgId, - id: serviceUserId, - title: DEFAULT_KEY_NAME - }) - ); - - // Invalidate service users query - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listOrganizationServiceUsers, - transport, - input: create(ListOrganizationServiceUsersRequestSchema, { - id: orgId - }), - cardinality: 'finite' - }) - }); - - // Seed listServiceUserTokens cache with the new token - const listTokensQueryKey = createConnectQueryKey({ - schema: FrontierServiceQueries.listServiceUserTokens, - transport, - input: create(ListServiceUserTokensRequestSchema, { - id: serviceUserId, - orgId - }), - cardinality: 'finite' - }); - - queryClient.setQueryData( - listTokensQueryKey, - create(ListServiceUserTokensResponseSchema, { - tokens: tokenResponse.token ? [tokenResponse.token] : [] - }) - ); - - toast.success('Service user created'); - onCreated?.(serviceUserId); - } catch (error: unknown) { - toast.error('Something went wrong', { - description: error instanceof Error ? error.message : 'Unknown error' - }); - } - }, - [ - orgId, - ownerRoleId, - createServiceUser, - setProjectMemberRole, - createServiceUserToken, - queryClient, - transport, - onCreated - ] - ); - - return ( - - -
- - - - New Service Account - - cross - - - - - - - Create a dedicated service account to facilitate secure API - interactions on behalf of the{' '} - {t.organization({ case: 'lower' })}. - - {isProjectsLoading ? ( - - ) : ( - - )} - - - {isProjectsLoading ? ( - - ) : ( - { - const { ref, onChange, ...rest } = field; - return ( - - ); - }} - name="project_id" - control={control} - /> - )} - - {errors.project_id && String(errors.project_id?.message)} - - - - - - - - - - -
-
-
- ); -}; diff --git a/web/sdk/react/views/api-keys/list/api-keys-columns.tsx b/web/sdk/react/views/api-keys/list/api-keys-columns.tsx deleted file mode 100644 index 3d5b00e11..000000000 --- a/web/sdk/react/views/api-keys/list/api-keys-columns.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { TrashIcon } from '@radix-ui/react-icons'; -import { Button, type DataTableColumnDef, Flex, Text } from '@raystack/apsara'; -import type { ServiceUser } from '~/src'; -import { timestampToDayjs } from '~/utils/timestamp'; -import type { Timestamp } from '@bufbuild/protobuf/wkt'; -import React from 'react'; - -interface GetColumnsOptions { - dateFormat: string; - onDeleteClick?: (id: string) => void; -} - -export const getColumns = ({ - dateFormat, - onDeleteClick -}: GetColumnsOptions): DataTableColumnDef[] => { - return [ - { - header: 'Name', - accessorKey: 'title', - cell: ({ row, getValue }) => { - const value = getValue() as string; - return {value}; - } - }, - { - header: 'Created on', - accessorKey: 'createdAt', - cell: ({ row, getValue }) => { - const value = getValue() as Timestamp | undefined; - return ( - - {timestampToDayjs(value)?.format(dateFormat) ?? '-'} - - ); - } - }, - { - header: '', - accessorKey: 'id', - enableSorting: false, - cell: ({ row, getValue }) => { - const value = getValue() as string; - return ( - - ); - } - } - ]; -}; diff --git a/web/sdk/react/views/api-keys/list/api-keys-list-page.tsx b/web/sdk/react/views/api-keys/list/api-keys-list-page.tsx deleted file mode 100644 index 4616743aa..000000000 --- a/web/sdk/react/views/api-keys/list/api-keys-list-page.tsx +++ /dev/null @@ -1,305 +0,0 @@ -import { - Flex, - EmptyState, - Button, - Skeleton, - Image, - DataTable -} from '@raystack/apsara'; -import keyIcon from '~/react/assets/key.svg'; -import { PageHeader } from '~/react/components/common/page-header'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { DEFAULT_DATE_FORMAT } from '~/react/utils/constants'; -import { useMemo, useState } from 'react'; -import { PERMISSIONS, shouldShowComponent } from '~/utils'; -import { usePermissions } from '~/react/hooks/usePermissions'; -import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; -import { getColumns } from './api-keys-columns'; -import { useTerminology } from '~/react/hooks/useTerminology'; -import { useQuery } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { - FrontierServiceQueries, - ListOrganizationServiceUsersRequestSchema, - type ServiceUser -} from '@raystack/proton/frontier'; - -import sharedStyles from '../../../components/organization/styles.module.css'; -import styles from './api-keys.module.css'; -import { AddServiceAccountDialog } from './add-service-account-dialog'; -import { DeleteServiceAccountDialog } from './delete-service-account-dialog'; - -const NoServiceAccounts = ({ - onCreateClick -}: { - onCreateClick: () => void; -}) => { - const t = useTerminology(); - - return ( - - } - heading="No service account found" - subHeading={`Create a new account to use the APIs of ${t.appName()} platform`} - primaryAction={ - - } - /> - - ); -}; - -const NoAccess = () => { - return ( - - } - heading="Restricted Access" - subHeading="Admin access required, please reach out to your admin incase you want to generate a key" - /> - - ); -}; - -interface ApiKeysHeaderProps { - isLoading?: boolean; -} - -const ApiKeysHeader = ({ isLoading }: ApiKeysHeaderProps) => { - const t = useTerminology(); - - if (isLoading) { - return ( - - - - - ); - } - - return ( - - ); -}; - -const useAccess = (orgId?: string) => { - const resource = `app/organization:${orgId}`; - const listOfPermissionsToCheck = useMemo(() => { - return [ - { - permission: PERMISSIONS.UpdatePermission, - resource: resource - } - ]; - }, [resource]); - - const { permissions, isFetching: isPermissionsFetching } = usePermissions( - listOfPermissionsToCheck, - !!orgId - ); - - const canUpdateWorkspace = useMemo(() => { - return shouldShowComponent( - permissions, - `${PERMISSIONS.UpdatePermission}::${resource}` - ); - }, [permissions, resource]); - - return { - isPermissionsFetching, - canUpdateWorkspace - }; -}; - -interface ServiceAccountsTableProps { - isLoading: boolean; - serviceUsers: ServiceUser[]; - dateFormat?: string; - onServiceAccountClick?: (id: string) => void; - onCreateClick: () => void; - onDeleteClick: (id: string) => void; -} - -const ServiceAccountsTable = ({ - isLoading, - serviceUsers, - dateFormat, - onServiceAccountClick, - onCreateClick, - onDeleteClick -}: ServiceAccountsTableProps) => { - const columns = getColumns({ - dateFormat: dateFormat || DEFAULT_DATE_FORMAT, - onDeleteClick - }); - - return ( - onServiceAccountClick?.(row.id)} - > - - - - {isLoading ? ( - - ) : ( - - )} - - {isLoading ? ( - - ) : ( - - )} - - - - - ); -}; - -export interface ApiKeysListPageProps { - onServiceAccountClick?: (id: string) => void; -} - -export default function ApiKeysListPage({ - onServiceAccountClick -}: ApiKeysListPageProps) { - const { - activeOrganization: organization, - isActiveOrganizationLoading, - config - } = useFrontier(); - - const { isPermissionsFetching, canUpdateWorkspace } = useAccess( - organization?.id - ); - - const { data: serviceUsersData, isLoading: isServiceUsersLoading } = useQuery( - FrontierServiceQueries.listOrganizationServiceUsers, - create(ListOrganizationServiceUsersRequestSchema, { - id: organization?.id ?? '' - }), - { - enabled: Boolean(organization?.id) && canUpdateWorkspace - } - ); - - const serviceUsers = useMemo( - () => serviceUsersData?.serviceusers ?? [], - [serviceUsersData] - ); - - const isLoading = - isActiveOrganizationLoading || - isPermissionsFetching || - isServiceUsersLoading; - - const serviceAccountsCount: number = serviceUsers?.length; - - const [showAddDialog, setShowAddDialog] = useState(false); - - const [deleteState, setDeleteState] = useState({ - open: false, - serviceAccountId: '' - }); - - const handleDeleteOpenChange = (value: boolean) => { - if (!value) { - setDeleteState({ open: false, serviceAccountId: '' }); - } else { - setDeleteState(prev => ({ ...prev, open: value })); - } - }; - - const handleDeleteClick = (id: string) => { - setDeleteState({ open: true, serviceAccountId: id }); - }; - - const handleAddOpenChange = (value: boolean) => { - setShowAddDialog(value); - }; - - const handleCreated = (serviceUserId: string) => { - setShowAddDialog(false); - onServiceAccountClick?.(serviceUserId); - }; - - return ( - - - - - - {canUpdateWorkspace || isLoading ? ( - serviceAccountsCount > 0 || isLoading ? ( - - setShowAddDialog(true)} - onDeleteClick={handleDeleteClick} - /> - - ) : ( - setShowAddDialog(true)} /> - ) - ) : ( - - )} - - - - - ); -} diff --git a/web/sdk/react/views/api-keys/list/api-keys.module.css b/web/sdk/react/views/api-keys/list/api-keys.module.css deleted file mode 100644 index e34dccef7..000000000 --- a/web/sdk/react/views/api-keys/list/api-keys.module.css +++ /dev/null @@ -1,64 +0,0 @@ -.container { - height: 100%; - width: 100%; - overflow: hidden; -} - -.content { - height: 100%; - width: 100%; - padding: var(--rs-space-9) var(--rs-space-11); - overflow: hidden; -} - -.stateContent { - padding: var(--rs-space-15) var(--rs-space-11); -} - -.flex1 { - flex: 1; -} - -.tableToolbarSearchWrapper { - max-width: 360px; - width: 100%; -} - -.tableToolbar { - border: 0; - margin-bottom: var(--rs-space-5); -} - -.addDialogContent { - padding: 0; - max-width: 400px; - width: 100%; -} - -.overlay { - background-color: rgba(104, 112, 118, 0.5); -} - -.tableWrapper { - display: flex; - flex-direction: column; - flex: 1; - min-height: 0; - overflow: hidden; -} - -.tableRoot { - flex: 1; - overflow-y: auto; - overflow-x: hidden; - min-height: 0; -} - -.tableHeader { - z-index: 1; -} - -.tableSearchWrapper { - max-width: 500px; - flex: 1; -} diff --git a/web/sdk/react/views/api-keys/list/delete-service-account-dialog.tsx b/web/sdk/react/views/api-keys/list/delete-service-account-dialog.tsx deleted file mode 100644 index 57044cf70..000000000 --- a/web/sdk/react/views/api-keys/list/delete-service-account-dialog.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Button, Flex, Text, toast, Image, Dialog } from '@raystack/apsara'; -import cross from '~/react/assets/cross.svg'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import styles from './api-keys.module.css'; -import { useQueryClient } from '@tanstack/react-query'; -import { useMutation, createConnectQueryKey, useTransport } from '@connectrpc/connect-query'; -import { - FrontierServiceQueries, - ListOrganizationServiceUsersRequestSchema, - DeleteServiceUserRequestSchema -} from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; - -export interface DeleteServiceAccountDialogProps { - open: boolean; - onOpenChange?: (value: boolean) => void; - serviceAccountId: string; -} - -export const DeleteServiceAccountDialog = ({ - open, - onOpenChange, - serviceAccountId -}: DeleteServiceAccountDialogProps) => { - const { activeOrganization: organization } = useFrontier(); - const queryClient = useQueryClient(); - const transport = useTransport(); - - const orgId = organization?.id || ''; - - const handleClose = () => onOpenChange?.(false); - - const { mutateAsync: deleteServiceUser, isPending } = useMutation( - FrontierServiceQueries.deleteServiceUser - ); - - async function onDeleteClick() { - try { - await deleteServiceUser( - create(DeleteServiceUserRequestSchema, { - id: serviceAccountId, - orgId - }) - ); - - // Invalidate service users query - await queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.listOrganizationServiceUsers, - transport, - input: create(ListOrganizationServiceUsersRequestSchema, { - id: orgId - }), - cardinality: 'finite' - }) - }); - - handleClose(); - toast.success('Service account deleted'); - } catch (error: unknown) { - toast.error('Unable to delete service account', { - description: error instanceof Error ? error.message : 'Unknown error' - }); - } - } - - return ( - - - - - - Delete Service Account - - - cross - - - - - - - This is an irreversible and permanent action doing this might - result in deletion of the service account and the keys associated - with it. Do you wish to proceed? - - - - - - - - - - - - - ); -}; diff --git a/web/sdk/react/views/api-keys/list/index.ts b/web/sdk/react/views/api-keys/list/index.ts deleted file mode 100644 index 719fbeb51..000000000 --- a/web/sdk/react/views/api-keys/list/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { default as ApiKeysListPage } from './api-keys-list-page'; -export type { ApiKeysListPageProps } from './api-keys-list-page'; - -export { AddServiceAccountDialog } from './add-service-account-dialog'; -export type { AddServiceAccountDialogProps } from './add-service-account-dialog'; - -export { DeleteServiceAccountDialog } from './delete-service-account-dialog'; -export type { DeleteServiceAccountDialogProps } from './delete-service-account-dialog'; diff --git a/web/sdk/react/views-new/auth/magic-link-verify/index.ts b/web/sdk/react/views/auth/magic-link-verify/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/magic-link-verify/index.ts rename to web/sdk/react/views/auth/magic-link-verify/index.ts diff --git a/web/sdk/react/views-new/auth/magic-link-verify/magic-link-verify-view.module.css b/web/sdk/react/views/auth/magic-link-verify/magic-link-verify-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/magic-link-verify/magic-link-verify-view.module.css rename to web/sdk/react/views/auth/magic-link-verify/magic-link-verify-view.module.css diff --git a/web/sdk/react/views-new/auth/magic-link-verify/magic-link-verify-view.tsx b/web/sdk/react/views/auth/magic-link-verify/magic-link-verify-view.tsx similarity index 99% rename from web/sdk/react/views-new/auth/magic-link-verify/magic-link-verify-view.tsx rename to web/sdk/react/views/auth/magic-link-verify/magic-link-verify-view.tsx index 9d5189e08..4abb61578 100644 --- a/web/sdk/react/views-new/auth/magic-link-verify/magic-link-verify-view.tsx +++ b/web/sdk/react/views/auth/magic-link-verify/magic-link-verify-view.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Button, Text, Link, Flex, Input } from '@raystack/apsara-v1'; +import { Button, Text, Link, Flex, Input } from '@raystack/apsara'; import { ChangeEvent, ComponentPropsWithRef, diff --git a/web/sdk/react/views-new/auth/magic-link/index.ts b/web/sdk/react/views/auth/magic-link/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/magic-link/index.ts rename to web/sdk/react/views/auth/magic-link/index.ts diff --git a/web/sdk/react/views-new/auth/magic-link/magic-link-view.module.css b/web/sdk/react/views/auth/magic-link/magic-link-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/magic-link/magic-link-view.module.css rename to web/sdk/react/views/auth/magic-link/magic-link-view.module.css diff --git a/web/sdk/react/views-new/auth/magic-link/magic-link-view.tsx b/web/sdk/react/views/auth/magic-link/magic-link-view.tsx similarity index 99% rename from web/sdk/react/views-new/auth/magic-link/magic-link-view.tsx rename to web/sdk/react/views/auth/magic-link/magic-link-view.tsx index 897213bbf..0bebaed46 100644 --- a/web/sdk/react/views-new/auth/magic-link/magic-link-view.tsx +++ b/web/sdk/react/views/auth/magic-link/magic-link-view.tsx @@ -5,7 +5,7 @@ import { Separator, Flex, Input -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { ComponentPropsWithRef, ReactNode, useCallback, useState } from 'react'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; diff --git a/web/sdk/react/views-new/auth/sign-in/index.ts b/web/sdk/react/views/auth/sign-in/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/sign-in/index.ts rename to web/sdk/react/views/auth/sign-in/index.ts diff --git a/web/sdk/react/views-new/auth/sign-in/sign-in-view.module.css b/web/sdk/react/views/auth/sign-in/sign-in-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/sign-in/sign-in-view.module.css rename to web/sdk/react/views/auth/sign-in/sign-in-view.module.css diff --git a/web/sdk/react/views-new/auth/sign-in/sign-in-view.tsx b/web/sdk/react/views/auth/sign-in/sign-in-view.tsx similarity index 97% rename from web/sdk/react/views-new/auth/sign-in/sign-in-view.tsx rename to web/sdk/react/views/auth/sign-in/sign-in-view.tsx index 7d5e03a12..7ea61e48a 100644 --- a/web/sdk/react/views-new/auth/sign-in/sign-in-view.tsx +++ b/web/sdk/react/views/auth/sign-in/sign-in-view.tsx @@ -1,4 +1,4 @@ -import { Link, Text, Flex } from '@raystack/apsara-v1'; +import { Link, Text, Flex } from '@raystack/apsara'; import { ComponentPropsWithRef, ReactNode, useCallback } from 'react'; import { useMutation, useQuery } from '@connectrpc/connect-query'; import { FrontierServiceQueries } from '@raystack/proton/frontier'; diff --git a/web/sdk/react/views-new/auth/sign-up/index.ts b/web/sdk/react/views/auth/sign-up/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/sign-up/index.ts rename to web/sdk/react/views/auth/sign-up/index.ts diff --git a/web/sdk/react/views-new/auth/sign-up/sign-up-view.module.css b/web/sdk/react/views/auth/sign-up/sign-up-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/sign-up/sign-up-view.module.css rename to web/sdk/react/views/auth/sign-up/sign-up-view.module.css diff --git a/web/sdk/react/views-new/auth/sign-up/sign-up-view.tsx b/web/sdk/react/views/auth/sign-up/sign-up-view.tsx similarity index 97% rename from web/sdk/react/views-new/auth/sign-up/sign-up-view.tsx rename to web/sdk/react/views/auth/sign-up/sign-up-view.tsx index e0e8a213d..0f9c074a9 100644 --- a/web/sdk/react/views-new/auth/sign-up/sign-up-view.tsx +++ b/web/sdk/react/views/auth/sign-up/sign-up-view.tsx @@ -1,4 +1,4 @@ -import { Link, Text, Flex } from '@raystack/apsara-v1'; +import { Link, Text, Flex } from '@raystack/apsara'; import { ComponentPropsWithRef, ReactNode, useCallback } from 'react'; import { useMutation, useQuery } from '@connectrpc/connect-query'; import { FrontierServiceQueries } from '@raystack/proton/frontier'; diff --git a/web/sdk/react/views-new/auth/subscribe/index.ts b/web/sdk/react/views/auth/subscribe/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/subscribe/index.ts rename to web/sdk/react/views/auth/subscribe/index.ts diff --git a/web/sdk/react/views-new/auth/subscribe/subscribe-view.module.css b/web/sdk/react/views/auth/subscribe/subscribe-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/subscribe/subscribe-view.module.css rename to web/sdk/react/views/auth/subscribe/subscribe-view.module.css diff --git a/web/sdk/react/views-new/auth/subscribe/subscribe-view.tsx b/web/sdk/react/views/auth/subscribe/subscribe-view.tsx similarity index 99% rename from web/sdk/react/views-new/auth/subscribe/subscribe-view.tsx rename to web/sdk/react/views/auth/subscribe/subscribe-view.tsx index 9aede705b..d76e4c4f5 100644 --- a/web/sdk/react/views-new/auth/subscribe/subscribe-view.tsx +++ b/web/sdk/react/views/auth/subscribe/subscribe-view.tsx @@ -14,7 +14,7 @@ import { toastManager, Image, EmptyState -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useMutation } from '@connectrpc/connect-query'; import { CreateProspectPublicRequestSchema, diff --git a/web/sdk/react/views-new/auth/updates/index.ts b/web/sdk/react/views/auth/updates/index.ts similarity index 100% rename from web/sdk/react/views-new/auth/updates/index.ts rename to web/sdk/react/views/auth/updates/index.ts diff --git a/web/sdk/react/views-new/auth/updates/updates-view.module.css b/web/sdk/react/views/auth/updates/updates-view.module.css similarity index 100% rename from web/sdk/react/views-new/auth/updates/updates-view.module.css rename to web/sdk/react/views/auth/updates/updates-view.module.css diff --git a/web/sdk/react/views-new/auth/updates/updates-view.tsx b/web/sdk/react/views/auth/updates/updates-view.tsx similarity index 99% rename from web/sdk/react/views-new/auth/updates/updates-view.tsx rename to web/sdk/react/views/auth/updates/updates-view.tsx index 0479b6275..0284cdb0d 100644 --- a/web/sdk/react/views-new/auth/updates/updates-view.tsx +++ b/web/sdk/react/views/auth/updates/updates-view.tsx @@ -2,7 +2,7 @@ import { yupResolver } from '@hookform/resolvers/yup'; import { type ReactNode } from 'react'; -import { Button, Flex, Text, Switch, Skeleton } from '@raystack/apsara-v1'; +import { Button, Flex, Text, Switch, Skeleton } from '@raystack/apsara'; import { Controller, useForm } from 'react-hook-form'; import * as yup from 'yup'; import { PREFERENCE_OPTIONS } from '~/react/utils/constants'; diff --git a/web/sdk/react/views/billing/billing-page.tsx b/web/sdk/react/views/billing/billing-page.tsx deleted file mode 100644 index 5723835a6..000000000 --- a/web/sdk/react/views/billing/billing-page.tsx +++ /dev/null @@ -1,317 +0,0 @@ -import { - Button, - Skeleton, - Text, - Flex, - toast, - Tooltip, - Link -} from '@raystack/apsara'; -import { PageHeader } from '~/react/components/common/page-header'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { - BillingAccount, - ListInvoicesRequestSchema, - FrontierServiceQueries, - CreateCheckoutRequestSchema -} from '@raystack/proton/frontier'; -import { useQuery as useConnectQuery } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { useMutation } from '~hooks'; -import Invoices from './invoices'; -import qs from 'query-string'; -import sharedStyles from '../../components/organization/styles.module.css'; -import billingStyles from './billing.module.css'; - -import { UpcomingBillingCycle } from './upcoming-billing-cycle'; -import { PaymentIssue } from './payment-issue'; -import { UpcomingPlanChangeBanner } from '~/react/components/common/upcoming-plan-change-banner'; -import { PaymentMethod } from './payment-method'; -import { useBillingPermission } from '~/react/hooks/useBillingPermission'; -import { ConfirmCycleSwitchDialog } from './confirm-cycle-switch-dialog'; - -interface BillingHeaderProps { - billingSupportEmail?: string; - isLoading?: boolean; -} - -const BillingHeader = ({ - billingSupportEmail, - isLoading -}: BillingHeaderProps) => { - if (isLoading) { - return ( - - - - - ); - } - - return ( - - Oversee your billing and invoices.{' '} - For more details, contact{' '} - - {billingSupportEmail} - - - ) : ( - 'Oversee your billing and invoices.' - ) - } - /> - ); -}; - - -interface BillingDetailsProps { - billingAccount?: BillingAccount; - onAddDetailsClick?: () => void; - isLoading: boolean; - isAllowed: boolean; - disabled?: boolean; -} - -const BillingDetails = ({ - billingAccount, - onAddDetailsClick = () => { }, - isLoading, - isAllowed, - disabled = false -}: BillingDetailsProps) => { - const btnText = - billingAccount?.email || billingAccount?.name ? 'Update' : 'Add details'; - const isButtonDisabled = isLoading || disabled; - return ( -
- - Billing Details - {isAllowed ? ( - - - - ) : null} - - - Name - - {isLoading ? : billingAccount?.name || 'N/A'} - - - - Email - - {isLoading ? : billingAccount?.email || 'N/A'} - - -
- ); -}; - -export interface BillingPageProps { - onNavigateToPlans?: () => void; -} - -export default function BillingPage({ onNavigateToPlans }: BillingPageProps) { - const { - billingAccount, - isBillingAccountLoading, - config, - activeSubscription, - isActiveSubscriptionLoading, - paymentMethod, - organizationKyc, - isOrganizationKycLoading, - activeOrganization - } = useFrontier(); - - const { isAllowed, isFetching } = useBillingPermission(); - - const { - data: invoicesData, - isLoading: isInvoicesLoading, - error: invoicesError - } = useConnectQuery( - FrontierServiceQueries.listInvoices, - create(ListInvoicesRequestSchema, { - orgId: activeOrganization?.id || '', - nonzeroAmountOnly: true - }), - { - enabled: !!activeOrganization?.id - } - ); - - const invoices = useMemo(() => invoicesData?.invoices || [], [invoicesData]); - - useEffect(() => { - if (invoicesError) { - toast.error('Failed to load invoices', { - description: invoicesError?.message - }); - } - }, [invoicesError]); - - const { mutateAsync: createCheckoutMutation } = useMutation( - FrontierServiceQueries.createCheckout, - { - onError: (err: Error) => { - console.error(err); - toast.error('Something went wrong', { - description: err?.message - }); - } - } - ); - - const onAddDetailsClick = useCallback(async () => { - const orgId = activeOrganization?.id || ''; - if (!orgId) return; - - try { - const query = qs.stringify( - { - details: btoa( - qs.stringify({ - organization_id: activeOrganization?.id || '', - type: 'billing' - }) - ), - checkout_id: '{{.CheckoutID}}' - }, - { encode: false } - ); - const cancel_url = `${config?.billing?.cancelUrl}?${query}`; - const success_url = `${config?.billing?.successUrl}?${query}`; - - const resp = await createCheckoutMutation( - create(CreateCheckoutRequestSchema, { - orgId: activeOrganization?.id || '', - cancelUrl: cancel_url, - successUrl: success_url, - setupBody: { - paymentMethod: false, - customerPortal: true - } - }) - ); - const checkoutUrl = resp?.checkoutSession?.checkoutUrl; - if (checkoutUrl) { - window.location.href = checkoutUrl; - } - } catch (err) { - console.error(err); - toast.error('Something went wrong'); - } - }, [ - activeOrganization?.id, - createCheckoutMutation, - config?.billing?.cancelUrl, - config?.billing?.successUrl - ]); - - const isLoading = - isBillingAccountLoading || - isActiveSubscriptionLoading || - isInvoicesLoading || - isFetching || - isOrganizationKycLoading; - - const isOrganizationKycCompleted = organizationKyc?.status === true; - - const [cycleSwitchState, setCycleSwitchState] = useState({ - open: false, - planId: '' - }); - - const handleCycleSwitchOpenChange = (value: boolean) => { - if (!value) { - setCycleSwitchState({ open: false, planId: '' }); - } else { - setCycleSwitchState(prev => ({ ...prev, open: value })); - } - }; - - const handleCycleSwitchClick = (planId: string) => { - setCycleSwitchState({ open: true, planId }); - }; - - return ( - - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/web/sdk/react/views-new/billing/billing-view.module.css b/web/sdk/react/views/billing/billing-view.module.css similarity index 100% rename from web/sdk/react/views-new/billing/billing-view.module.css rename to web/sdk/react/views/billing/billing-view.module.css diff --git a/web/sdk/react/views-new/billing/billing-view.tsx b/web/sdk/react/views/billing/billing-view.tsx similarity index 99% rename from web/sdk/react/views-new/billing/billing-view.tsx rename to web/sdk/react/views/billing/billing-view.tsx index b9f096914..a6ad8386c 100644 --- a/web/sdk/react/views-new/billing/billing-view.tsx +++ b/web/sdk/react/views/billing/billing-view.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo } from 'react'; import qs from 'query-string'; -import { Flex, Dialog, EmptyState, toastManager } from '@raystack/apsara-v1'; +import { Flex, Dialog, EmptyState, toastManager } from '@raystack/apsara'; import { CreateCheckoutRequestSchema, ListInvoicesRequestSchema, diff --git a/web/sdk/react/views/billing/billing.module.css b/web/sdk/react/views/billing/billing.module.css deleted file mode 100644 index 0db78dc77..000000000 --- a/web/sdk/react/views/billing/billing.module.css +++ /dev/null @@ -1,87 +0,0 @@ -.detailsBox { - padding: var(--rs-space-4); - display: flex; - border: 0.5px solid var(--rs-color-border-base-primary); - background: var(--rs-color-background-base-primary); - border-radius: var(--rs-space-2); - min-width: 342px; - gap: 16px; - flex-direction: column; - flex: 1; -} - -.detailsBoxHeading { - color: var(--rs-color-foreground-base-primary); - font-size: 14px; - font-weight: 500; - line-height: 20px; - letter-spacing: 0.1px; -} - -.detailsBoxRowLabel { - color: var(--rs-color-foreground-base-secondary); - font-size: 11px; - font-weight: 500; - line-height: 16px; - letter-spacing: 0.5px; -} - -.detailsBoxRowValue { - color: var(--rs-color-foreground-base-primary); - font-size: 14px; - font-weight: 400; - line-height: 20px; - letter-spacing: 0.25px; -} - -.currentPlanInfoBox { - padding: var(--rs-space-3); - border-radius: var(--rs-space-2); - border: 0.5px solid var(--rs-color-border-accent-primary); - background: var(--rs-color-background-accent-primary); -} - -.billingCycleBox { - padding: var(--rs-space-4); - border-radius: var(--rs-space-2); - border: 0.5px solid var(--rs-color-border-base-primary); - background: var(--rs-color-background-base-primary); -} - -.currentPlanInfoText { - color: var(--rs-color-foreground-base-primary); - font-weight: 400; -} - -.flex1 { - flex: 1; -} - -.paymentIssueBox { - padding: var(--rs-space-3); - border-radius: var(--rs-space-2); - border: 0.5px solid var(--rs-color-border-danger-primary); - background: var(--rs-color-background-danger-primary); -} - -.paymentIssueText { - color: var(--rs-color-foreground-danger-primary); -} - -.retryPaymentBtn { - background: var(--rs-color-background-danger-primary); - color: var(--rs-color-foreground-base-primary); -} - -.retryPaymentBtn:focus, -.retryPaymentBtn:hover { - outline: none; - font-weight: 500; -} - -.changeBannerBox { - padding: var(--rs-space-3); - border-radius: var(--rs-space-2); - border: 0.5px solid var(--rs-color-border-accent-primary); - background: var(--rs-color-background-accent-primary); -} diff --git a/web/sdk/react/views-new/billing/components/billing-details-card.tsx b/web/sdk/react/views/billing/components/billing-details-card.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/billing-details-card.tsx rename to web/sdk/react/views/billing/components/billing-details-card.tsx index a99864204..a937672ec 100644 --- a/web/sdk/react/views-new/billing/components/billing-details-card.tsx +++ b/web/sdk/react/views/billing/components/billing-details-card.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Button, Skeleton, Text, Flex, Tooltip } from '@raystack/apsara-v1'; +import { Button, Skeleton, Text, Flex, Tooltip } from '@raystack/apsara'; import type { BillingAccount } from '@raystack/proton/frontier'; import { convertBillingAddressToString } from '../../../utils'; import styles from '../billing-view.module.css'; diff --git a/web/sdk/react/views-new/billing/components/confirm-cycle-switch-dialog.tsx b/web/sdk/react/views/billing/components/confirm-cycle-switch-dialog.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/confirm-cycle-switch-dialog.tsx rename to web/sdk/react/views/billing/components/confirm-cycle-switch-dialog.tsx index 7bdb2e474..6c2417b47 100644 --- a/web/sdk/react/views-new/billing/components/confirm-cycle-switch-dialog.tsx +++ b/web/sdk/react/views/billing/components/confirm-cycle-switch-dialog.tsx @@ -9,7 +9,7 @@ import { Flex, Dialog, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useFrontier } from '../../../contexts/FrontierContext'; import { getPlanIntervalName, getPlanPrice } from '../../../utils'; import { DEFAULT_DATE_FORMAT } from '../../../utils/constants'; diff --git a/web/sdk/react/views-new/billing/components/invoices.tsx b/web/sdk/react/views/billing/components/invoices.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/invoices.tsx rename to web/sdk/react/views/billing/components/invoices.tsx index c674a539b..b1a180f43 100644 --- a/web/sdk/react/views-new/billing/components/invoices.tsx +++ b/web/sdk/react/views/billing/components/invoices.tsx @@ -8,12 +8,12 @@ import { Flex, Text, Amount -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import type { DataTableColumnDef, DataTableQuery, DataTableSort -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { ExclamationTriangleIcon, } from '@radix-ui/react-icons'; diff --git a/web/sdk/react/views-new/billing/components/payment-issue.tsx b/web/sdk/react/views/billing/components/payment-issue.tsx similarity index 96% rename from web/sdk/react/views-new/billing/components/payment-issue.tsx rename to web/sdk/react/views/billing/components/payment-issue.tsx index 9a815385e..d16326591 100644 --- a/web/sdk/react/views-new/billing/components/payment-issue.tsx +++ b/web/sdk/react/views/billing/components/payment-issue.tsx @@ -1,7 +1,7 @@ 'use client'; import { useCallback } from 'react'; -import { Button, Text, Flex } from '@raystack/apsara-v1'; +import { Button, Text, Flex } from '@raystack/apsara'; import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; import { INVOICE_STATES, SUBSCRIPTION_STATES } from '../../../utils/constants'; import { Subscription, Invoice } from '@raystack/proton/frontier'; diff --git a/web/sdk/react/views-new/billing/components/payment-method-card.tsx b/web/sdk/react/views/billing/components/payment-method-card.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/payment-method-card.tsx rename to web/sdk/react/views/billing/components/payment-method-card.tsx index 762e3f7ae..98db2c665 100644 --- a/web/sdk/react/views-new/billing/components/payment-method-card.tsx +++ b/web/sdk/react/views/billing/components/payment-method-card.tsx @@ -1,7 +1,7 @@ 'use client'; import qs from 'query-string'; -import { Button, Skeleton, Text, Flex, Tooltip, toastManager } from '@raystack/apsara-v1'; +import { Button, Skeleton, Text, Flex, Tooltip, toastManager } from '@raystack/apsara'; import { useFrontier } from '../../../contexts/FrontierContext'; import { PaymentMethod as PaymentMethodType, diff --git a/web/sdk/react/views-new/billing/components/upcoming-billing-cycle.tsx b/web/sdk/react/views/billing/components/upcoming-billing-cycle.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/upcoming-billing-cycle.tsx rename to web/sdk/react/views/billing/components/upcoming-billing-cycle.tsx index 4dc22b72e..9fe4a4ff1 100644 --- a/web/sdk/react/views-new/billing/components/upcoming-billing-cycle.tsx +++ b/web/sdk/react/views/billing/components/upcoming-billing-cycle.tsx @@ -18,7 +18,7 @@ import { Flex, Amount, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { InfoCircledIcon } from '@radix-ui/react-icons'; import { getPlanIntervalName, diff --git a/web/sdk/react/views-new/billing/components/upcoming-plan-change-banner.tsx b/web/sdk/react/views/billing/components/upcoming-plan-change-banner.tsx similarity index 99% rename from web/sdk/react/views-new/billing/components/upcoming-plan-change-banner.tsx rename to web/sdk/react/views/billing/components/upcoming-plan-change-banner.tsx index e6f368ed4..1210be633 100644 --- a/web/sdk/react/views-new/billing/components/upcoming-plan-change-banner.tsx +++ b/web/sdk/react/views/billing/components/upcoming-plan-change-banner.tsx @@ -1,7 +1,7 @@ 'use client'; import { useCallback, useMemo } from 'react'; -import { Button, Text, Flex, toastManager } from '@raystack/apsara-v1'; +import { Button, Text, Flex, toastManager } from '@raystack/apsara'; import { InfoCircledIcon } from '@radix-ui/react-icons'; import { useFrontier } from '../../../contexts/FrontierContext'; import { diff --git a/web/sdk/react/views/billing/confirm-cycle-switch-dialog.tsx b/web/sdk/react/views/billing/confirm-cycle-switch-dialog.tsx deleted file mode 100644 index 8488bbd6d..000000000 --- a/web/sdk/react/views/billing/confirm-cycle-switch-dialog.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import { useCallback, useMemo } from 'react'; -import { - Button, - Skeleton, - Image, - Text, - toast, - Flex, - Dialog -} from '@raystack/apsara'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { getPlanIntervalName, getPlanPrice } from '~/react/utils'; -import * as _ from 'lodash'; -import { DEFAULT_DATE_FORMAT } from '~/react/utils/constants'; -import cross from '~/react/assets/cross.svg'; -import orgStyles from '../../components/organization/organization.module.css'; -import { timestampToDayjs } from '~/utils/timestamp'; -import { usePlans } from '~/react/views/plans/hooks/usePlans'; - -export interface ConfirmCycleSwitchDialogProps { - open: boolean; - onOpenChange?: (value: boolean) => void; - planId: string; -} - -export function ConfirmCycleSwitchDialog({ - open, - onOpenChange, - planId -}: ConfirmCycleSwitchDialogProps) { - const { - activePlan, - paymentMethod, - config, - activeSubscription, - allPlans, - isAllPlansLoading - } = useFrontier(); - const dateFormat = config?.dateFormat || DEFAULT_DATE_FORMAT; - - const handleClose = useCallback( - () => onOpenChange?.(false), - [onOpenChange] - ); - - const { - checkoutPlan, - isLoading: isPlanActionLoading, - changePlan, - verifyPlanChange - } = usePlans(); - - const nextPlan = useMemo(() => { - if (planId && allPlans.length > 0) { - const plan = allPlans.find(p => p.id === planId); - return plan; - } - }, [planId, allPlans]); - - const nextPlanPrice = nextPlan ? getPlanPrice(nextPlan) : { amount: 0 }; - const isPaymentMethodRequired = - _.isEmpty(paymentMethod) && nextPlanPrice.amount > 0; - - const nextPlanIntervalName = getPlanIntervalName(nextPlan); - - const nextPlanMetadata = nextPlan?.metadata as Record; - const activePlanMetadata = activePlan?.metadata as Record; - - const isUpgrade = - (Number(nextPlanMetadata?.weightage) || 0) - - (Number(activePlanMetadata?.weightage) || 0) > - 0; - - const isLoading = isAllPlansLoading; - - async function onConfirm() { - const nextPlanId = nextPlan?.id; - if (!nextPlanId) return; - if (isPaymentMethodRequired) { - checkoutPlan({ - planId: nextPlanId, - isTrial: false, - onSuccess: data => { - window.location.href = data?.checkoutUrl as string; - } - }); - } else - changePlan({ - planId: nextPlanId, - onSuccess: async () => { - const planPhase = await verifyPlanChange({ - planId: nextPlanId - }); - if (planPhase) { - handleClose(); - const changeDate = timestampToDayjs(planPhase?.effectiveAt)?.format( - dateFormat - ); - toast.success(`Plan cycle switch successful`, { - description: `Your plan cycle will switched to ${nextPlanIntervalName} on ${changeDate}` - }); - } - }, - immediate: isUpgrade - }); - } - - const cycleSwitchDate = activeSubscription?.currentPeriodEndAt - ? timestampToDayjs(activeSubscription?.currentPeriodEndAt)?.format( - config?.dateFormat || DEFAULT_DATE_FORMAT - ) - : 'the next billing cycle'; - - return ( - - - - - - Switch billing cycle - - - cross - - - - - - {isLoading ? ( - - ) : ( - - - Current cycle: - - - {getPlanIntervalName(activePlan)} - - - )} - {isLoading ? ( - - ) : ( - - - New cycle: - - - {nextPlanIntervalName} ( - {isUpgrade - ? 'effective immediately' - : `effective from ${cycleSwitchDate}`} - ) - - - )} - - - - - - - - - - - - ); -} diff --git a/web/sdk/react/views/billing/index.ts b/web/sdk/react/views/billing/index.ts index 440e7ed2b..edd0f7437 100644 --- a/web/sdk/react/views/billing/index.ts +++ b/web/sdk/react/views/billing/index.ts @@ -1,5 +1,2 @@ -export { default as BillingPage } from './billing-page'; -export type { BillingPageProps } from './billing-page'; - -export { ConfirmCycleSwitchDialog } from './confirm-cycle-switch-dialog'; -export type { ConfirmCycleSwitchDialogProps } from './confirm-cycle-switch-dialog'; +export { BillingView } from './billing-view'; +export type { BillingViewProps } from './billing-view'; diff --git a/web/sdk/react/views/billing/invoices/index.tsx b/web/sdk/react/views/billing/invoices/index.tsx deleted file mode 100644 index 3d8735602..000000000 --- a/web/sdk/react/views/billing/invoices/index.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import type { DataTableColumnDef } from '@raystack/apsara'; -import { - EmptyState, - Flex, - Link, - Text, - DataTable, - Amount -} from '@raystack/apsara'; -import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { DEFAULT_DATE_FORMAT, INVOICE_STATES } from '~/react/utils/constants'; -import type { Invoice } from '@raystack/proton/frontier'; -import { capitalize } from '~/utils'; -import { timestampToDayjs, type TimeStamp } from '~/utils/timestamp'; -import styles from './invoice.module.css'; - -interface InvoicesProps { - isLoading: boolean; - invoices: Invoice[]; -} - -interface getColumnsOptions { - dateFormat: string; -} - -export const getColumns: ( - options: getColumnsOptions -) => DataTableColumnDef[] = ({ dateFormat }) => [ - { - header: 'Date', - accessorKey: 'effectiveAt', - cell: ({ row, getValue }) => { - const value = - row.original?.state === INVOICE_STATES.DRAFT - ? row?.original?.dueDate - : (getValue() as TimeStamp); - const timestamp = value || row?.original?.createdAt; - const date = timestampToDayjs(timestamp); - return ( - - {date ? date.format(dateFormat) : '-'} - - ); - } - }, - { - header: 'Status', - accessorKey: 'state', - cell: ({ row, getValue }) => { - return ( - - {capitalize(getValue() as string)} - - ); - } - }, - { - header: 'Amount', - accessorKey: 'amount', - cell: ({ row, getValue }) => { - const value = Number(getValue()); - return ( - - - - - - ); - } - }, - { - header: '', - accessorKey: 'hostedUrl', - classNames: { - cell: styles.linkColumn - }, - enableSorting: false, - cell: ({ row, getValue }) => { - const link = getValue() as string; - return link ? ( - - View invoice - - ) : null; - } - } -]; - -const noDataChildren = ( - } - heading={'No previous invoices'} - /> -); - -export default function Invoices({ isLoading, invoices }: InvoicesProps) { - const { config } = useFrontier(); - - const columns = getColumns({ - dateFormat: config?.dateFormat || DEFAULT_DATE_FORMAT - }); - - return ( - - - - ); -} diff --git a/web/sdk/react/views/billing/invoices/invoice.module.css b/web/sdk/react/views/billing/invoices/invoice.module.css deleted file mode 100644 index 58c736d60..000000000 --- a/web/sdk/react/views/billing/invoices/invoice.module.css +++ /dev/null @@ -1,13 +0,0 @@ -.header { - margin-top: calc(-1 * var(--rs-space-9)); - padding-top: var(--rs-space-9); -} - -.linkColumn { - text-align: right; -} - -.linkColumn > a { - color: var(--rs-color-foreground-accent-primary); - text-decoration: none; -} diff --git a/web/sdk/react/views/billing/payment-issue.tsx b/web/sdk/react/views/billing/payment-issue.tsx deleted file mode 100644 index bb0e87de1..000000000 --- a/web/sdk/react/views/billing/payment-issue.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Button, Skeleton, Image, Text, Flex } from '@raystack/apsara'; -import { INVOICE_STATES, SUBSCRIPTION_STATES } from '~/react/utils/constants'; -import { Subscription, Invoice } from '@raystack/proton/frontier'; -import billingStyles from './billing.module.css'; -import exclamationTriangle from '~/react/assets/exclamation-triangle.svg'; -import { timestampToDayjs } from '~/utils/timestamp'; -import { useCallback } from 'react'; - -interface PaymentIssueProps { - isLoading?: boolean; - subscription?: Subscription; - invoices: Invoice[]; -} - -export function PaymentIssue({ - isLoading, - subscription, - invoices -}: PaymentIssueProps) { - const isPastDue = subscription?.state === SUBSCRIPTION_STATES.PAST_DUE; - const openInvoices = invoices - .filter(inv => inv.state === INVOICE_STATES.OPEN) - .sort((a, b) => { - const dateA = timestampToDayjs(a.dueDate); - const dateB = timestampToDayjs(b.dueDate); - if (!dateA || !dateB) return 0; - return dateA.isAfter(dateB) ? -1 : 1; - }); - - const onRetryPayment = useCallback(() => { - window.location.href = openInvoices[0]?.hostedUrl || ''; - }, [openInvoices]); - - return isLoading ? ( - - ) : isPastDue ? ( - - - Exclamation Triangle - - Your Payment is due. Please try again - - - - - - - ) : null; -} diff --git a/web/sdk/react/views/billing/payment-method.tsx b/web/sdk/react/views/billing/payment-method.tsx deleted file mode 100644 index c81328c55..000000000 --- a/web/sdk/react/views/billing/payment-method.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import qs from 'query-string'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import * as _ from 'lodash'; -import { Button, Skeleton, Text, Flex } from '@raystack/apsara'; -import billingStyles from './billing.module.css'; -import { - PaymentMethod as PaymentMethodType, - FrontierServiceQueries, - CreateCheckoutRequestSchema -} from '@raystack/proton/frontier'; -import { toast } from '@raystack/apsara'; -import { useMutation } from '~hooks'; -import { create } from '@bufbuild/protobuf'; - -interface PaymentMethodProps { - paymentMethod?: PaymentMethodType; - isLoading: boolean; - isAllowed: boolean; -} - -export const PaymentMethod = ({ - paymentMethod, - isLoading, - isAllowed -}: PaymentMethodProps) => { - const { config, billingAccount, activeOrganization } = useFrontier(); - - const { mutateAsync: createCheckoutMutation, isPending: isActionLoading } = - useMutation(FrontierServiceQueries.createCheckout, { - onError: (err: Error) => { - console.error(err); - toast.error('Something went wrong', { - description: err?.message - }); - } - }); - const { - cardLast4 = '', - cardExpiryMonth, - cardExpiryYear - } = paymentMethod || {}; - // TODO: change card digit as per card type - const cardDigit = 12; - const cardNumber = cardLast4 ? _.repeat('*', cardDigit) + cardLast4 : 'N/A'; - const cardExp = - cardExpiryMonth && cardExpiryYear - ? `${cardExpiryMonth}/${cardExpiryYear}` - : 'N/A'; - - const isPaymentMethodAvailable = cardLast4 !== ''; - - const updatePaymentMethod = async () => { - const orgId = activeOrganization?.id || ''; - - const query = qs.stringify( - { - details: btoa( - qs.stringify({ - organization_id: activeOrganization?.id, - type: 'billing' - }) - ), - checkout_id: '{{.CheckoutID}}' - }, - { encode: false } - ); - const cancel_url = `${config?.billing?.cancelUrl}?${query}`; - const success_url = `${config?.billing?.successUrl}?${query}`; - - const resp = await createCheckoutMutation( - create(CreateCheckoutRequestSchema, { - orgId: activeOrganization?.id || '', - cancelUrl: cancel_url, - successUrl: success_url, - setupBody: { - paymentMethod: true, - customerPortal: false - } - }) - ); - const checkoutUrl = resp?.checkoutSession?.checkoutUrl; - if (checkoutUrl) { - window.location.href = checkoutUrl; - } - }; - - function onClick() { - updatePaymentMethod(); - } - - const isBtnDisabled = isLoading || isActionLoading; - - return ( -
- - Payment method - {isAllowed ? ( - - ) : null} - - - - Card Number - - - {isLoading ? : cardNumber} - - - - - Expiry - - - {isLoading ? : cardExp} - - -
- ); -}; diff --git a/web/sdk/react/views/billing/upcoming-billing-cycle.tsx b/web/sdk/react/views/billing/upcoming-billing-cycle.tsx deleted file mode 100644 index 94ef2083a..000000000 --- a/web/sdk/react/views/billing/upcoming-billing-cycle.tsx +++ /dev/null @@ -1,277 +0,0 @@ -import { ReactNode, useEffect, useMemo } from 'react'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { - GetUpcomingInvoiceRequestSchema, - FrontierServiceQueries, - ListOrganizationUsersRequestSchema, - Plan -} from '@raystack/proton/frontier'; -import { useQuery as useConnectQuery } from '@connectrpc/connect-query'; -import { create } from '@bufbuild/protobuf'; -import { - Button, - Tooltip, - Image, - Skeleton, - Text, - Flex, - Amount, - toast -} from '@raystack/apsara'; -import { InfoCircledIcon } from '@radix-ui/react-icons'; -import { - getPlanIntervalName, - getPlanNameWithInterval, - makePlanSlug -} from '~/react/utils'; -import { NEGATIVE_BALANCE_TOOLTIP_MESSAGE } from '~/react/utils/constants'; -import { timestampToDayjs } from '~/utils/timestamp'; -import line from '~/react/assets/line.svg'; -import billingStyles from './billing.module.css'; - -function LabeledBillingData({ - label, - value -}: { - label: string; - value: string | ReactNode; -}) { - return ( - - - {label}: - - {value} - - ); -} - -interface PlanSwitchButtonProps { - nextPlan: Plan; - onCycleSwitchClick?: (planId: string) => void; -} - -function PlanSwitchButton({ nextPlan, onCycleSwitchClick }: PlanSwitchButtonProps) { - const intervalName = getPlanIntervalName(nextPlan).toLowerCase(); - - function onClick() { - onCycleSwitchClick?.(nextPlan.id || ''); - } - - return ( -
- -
- ); -} - -function getSwitchablePlan(plans: Plan[], currentPlan: Plan) { - const currentPlanMetaData = - (currentPlan?.metadata as Record) || {}; - const currentPlanSlug = - currentPlanMetaData?.plan_group_id || makePlanSlug(currentPlan); - const similarPlans = plans.filter(plan => { - const metaData = (plan?.metadata as Record) || {}; - const planSlug = metaData?.plan_group_id || makePlanSlug(plan); - return currentPlanSlug === planSlug && plan.id !== currentPlan.id; - }); - return similarPlans.length ? similarPlans[0] : null; -} - -interface UpcomingBillingCycleProps { - isAllowed: boolean; - isPermissionLoading: boolean; - onCycleSwitchClick?: (planId: string) => void; - onNavigateToPlans?: () => void; -} - -export const UpcomingBillingCycle = ({ - isAllowed, - isPermissionLoading, - onCycleSwitchClick, - onNavigateToPlans -}: UpcomingBillingCycleProps) => { - const { - billingAccount, - config, - activeSubscription, - trialSubscription, - isActiveOrganizationLoading, - basePlan, - allPlans, - isAllPlansLoading, - activeOrganization - } = useFrontier(); - - const { - data: upcomingInvoice, - isLoading: isInvoiceLoading, - error: invoiceError - } = useConnectQuery( - FrontierServiceQueries.getUpcomingInvoice, - create(GetUpcomingInvoiceRequestSchema, { - orgId: activeOrganization?.id || '' - }), - { - enabled: - !!activeOrganization?.id && - // This is to prevent fetching the upcoming invoice for offline billing accounts - !!billingAccount?.providerId, - select: data => data?.invoice - } - ); - - const { - data: memberCount = 0, - isLoading: isMemberCountLoading, - error: memberCountError - } = useConnectQuery( - FrontierServiceQueries.listOrganizationUsers, - create(ListOrganizationUsersRequestSchema, { - id: billingAccount?.orgId || '' - }), - { - enabled: !!billingAccount?.id && !!billingAccount?.orgId, - select: data => data?.users?.length || 0 - } - ); - - const { plan, switchablePlan } = useMemo(() => { - if (activeSubscription?.planId && allPlans.length > 0) { - const currentPlan = allPlans.find( - p => p.id === activeSubscription.planId - ); - const otherPlan = currentPlan - ? getSwitchablePlan(allPlans, currentPlan) - : null; - return { plan: currentPlan, switchablePlan: otherPlan }; - } - return { plan: null, switchablePlan: null }; - }, [activeSubscription?.planId, allPlans]); - - const planName = activeSubscription - ? getPlanNameWithInterval(plan ?? undefined) - : getPlanNameWithInterval(basePlan); - - const planInfo = - activeSubscription || basePlan - ? { - message: `You are subscribed to ${planName}.`, - action: { - label: 'Upgrade' - } - } - : { - message: 'You are not subscribed to any plan', - action: { - label: 'Subscribe' - } - }; - - const onActionBtnClick = () => { - onNavigateToPlans?.(); - }; - - const alreadyPhased = activeSubscription?.phases?.find( - phase => phase.planId === switchablePlan?.id - ); - - const error = memberCountError || invoiceError; - useEffect(() => { - if (error) { - console.error('Failed to get upcoming billing cycle details', error); - toast.error('Failed to get upcoming billing cycle details'); - } - }, [error]); - - const isLoading = - isActiveOrganizationLoading || - isInvoiceLoading || - isMemberCountLoading || - isAllPlansLoading || - isPermissionLoading; - - const isUserOnlyTrialing = !activeSubscription?.id && trialSubscription?.id; - const dueDate = upcomingInvoice?.dueDate || upcomingInvoice?.periodEndAt; - - return isLoading ? ( - - ) : dueDate && !isUserOnlyTrialing ? ( - - - - {switchablePlan && isAllowed && !alreadyPhased ? ( - - ) : null} - - - - line - - line - - - {Number(upcomingInvoice?.amount) < 0 ? ( - - - - ) : null} - - } - /> - - - ) : ( - - - - - {planInfo.message} - - - - - ); -}; diff --git a/web/sdk/react/views-new/create-organization/create-organization-view.module.css b/web/sdk/react/views/create-organization/create-organization-view.module.css similarity index 100% rename from web/sdk/react/views-new/create-organization/create-organization-view.module.css rename to web/sdk/react/views/create-organization/create-organization-view.module.css diff --git a/web/sdk/react/views-new/create-organization/create-organization-view.tsx b/web/sdk/react/views/create-organization/create-organization-view.tsx similarity index 99% rename from web/sdk/react/views-new/create-organization/create-organization-view.tsx rename to web/sdk/react/views/create-organization/create-organization-view.tsx index a4573db53..0241f4fbc 100644 --- a/web/sdk/react/views-new/create-organization/create-organization-view.tsx +++ b/web/sdk/react/views/create-organization/create-organization-view.tsx @@ -9,7 +9,7 @@ import { Field, Input, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { ComponentPropsWithRef } from 'react'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; diff --git a/web/sdk/react/views-new/create-organization/index.ts b/web/sdk/react/views/create-organization/index.ts similarity index 100% rename from web/sdk/react/views-new/create-organization/index.ts rename to web/sdk/react/views/create-organization/index.ts diff --git a/web/sdk/react/views-new/general/components/delete-organization-dialog.tsx b/web/sdk/react/views/general/components/delete-organization-dialog.tsx similarity index 99% rename from web/sdk/react/views-new/general/components/delete-organization-dialog.tsx rename to web/sdk/react/views/general/components/delete-organization-dialog.tsx index edff67f85..3519bb798 100644 --- a/web/sdk/react/views-new/general/components/delete-organization-dialog.tsx +++ b/web/sdk/react/views/general/components/delete-organization-dialog.tsx @@ -17,7 +17,7 @@ import { Input, Text, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useFrontier } from '../../../contexts/FrontierContext'; import { useTerminology } from '../../../hooks/useTerminology'; import { handleConnectError } from '~/utils/error'; diff --git a/web/sdk/react/views/general/delete-organization-dialog.tsx b/web/sdk/react/views/general/delete-organization-dialog.tsx deleted file mode 100644 index c5057c8c6..000000000 --- a/web/sdk/react/views/general/delete-organization-dialog.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import { useState } from 'react'; -import { - Button, - Checkbox, - toast, - Text, - Flex, - Dialog, - InputField -} from '@raystack/apsara'; - -import { yupResolver } from '@hookform/resolvers/yup'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { useMutation } from '@connectrpc/connect-query'; -import { - FrontierServiceQueries, - DeleteOrganizationRequestSchema -} from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; -import { useTerminology } from '~/react/hooks/useTerminology'; - -import styles from './general.module.css'; - -const orgSchema = yup - .object({ - title: yup.string() - }) - .required(); - -export interface DeleteOrganizationDialogProps { - open: boolean; - onOpenChange: (value: boolean) => void; - onDeleteSuccess?: () => void; -} - -export const DeleteOrganizationDialog = ({ - open, - onOpenChange, - onDeleteSuccess -}: DeleteOrganizationDialogProps) => { - const { - watch, - handleSubmit, - setError, - formState: { errors, isSubmitting }, - register - } = useForm({ - resolver: yupResolver(orgSchema) - }); - const t = useTerminology(); - const { activeOrganization: organization } = useFrontier(); - const { mutateAsync: deleteOrganization } = useMutation( - FrontierServiceQueries.deleteOrganization - ); - const [isAcknowledged, setIsAcknowledged] = useState(false); - - async function onSubmit(data: any) { - if (!organization?.id) return; - if (data.title !== organization.title) - return setError('title', { - message: `The ${t.organization({ case: 'lower' })} name does not match` - }); - - try { - const req = create(DeleteOrganizationRequestSchema, { - id: organization.id - }); - await deleteOrganization(req); - toast.success(`${t.organization({ case: 'capital' })} deleted`); - - onDeleteSuccess?.(); - } catch (error: any) { - toast.error('Something went wrong', { - description: - error?.message || - `Failed to delete ${t.organization({ case: 'capital' })}` - }); - } - } - - const title = watch('title', ''); - return ( - - - - - Verify {t.organization({ case: 'lower' })} deletion - - - -
- - - - This action can not be undone. This will permanently - delete all the projects and resources in{' '} - {organization?.title}. - - - - - - - setIsAcknowledged(v === true)} - data-test-id="frontier-sdk-delete-organization-checkbox" - /> - - I acknowledge and understand that all of the{' '} - {t.organization({ case: 'lower' })} data will be deleted and - want to proceed. - - - - - -
-
-
- ); -}; - diff --git a/web/sdk/react/views/general/general-organization.tsx b/web/sdk/react/views/general/general-organization.tsx deleted file mode 100644 index 1d94fcf9b..000000000 --- a/web/sdk/react/views/general/general-organization.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { yupResolver } from '@hookform/resolvers/yup'; -import { - Button, - Separator, - toast, - Tooltip, - Skeleton, - Box, - Flex, - InputField -} from '@raystack/apsara'; -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { - createConnectQueryKey, - useMutation, - useTransport -} from '@connectrpc/connect-query'; -import { useQueryClient } from '@tanstack/react-query'; -import { - FrontierServiceQueries, - UpdateOrganizationRequestSchema, - Organization -} from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; -import { AuthTooltipMessage } from '~/react/utils'; -import { AvatarUpload } from '~/react/components/avatar-upload'; -import { getInitials } from '~/utils'; -import { useTerminology } from '~/react/hooks/useTerminology'; -import styles from './general.module.css'; - -const generalSchema = yup - .object({ - avatar: yup.string().optional(), - title: yup.string().required('Name is a required field'), - name: yup.string().required('URL is a required field') - }) - .required(); - -type FormData = yup.InferType; - -export interface GeneralOrganizationProps { - organization?: Organization; - isLoading?: boolean; - canUpdateWorkspace?: boolean; -} - -export const GeneralOrganization = ({ - organization, - isLoading, - canUpdateWorkspace = false -}: GeneralOrganizationProps) => { - const t = useTerminology(); - const { setActiveOrganization } = useFrontier(); - const queryClient = useQueryClient(); - const transport = useTransport(); - const { mutateAsync: updateOrganization } = useMutation( - FrontierServiceQueries.updateOrganization, - { - onSuccess: data => { - if (data.organization) { - setActiveOrganization(data.organization); - queryClient.invalidateQueries({ - queryKey: createConnectQueryKey({ - schema: FrontierServiceQueries.getOrganization, - transport, - input: { id: organization?.id || '' }, - cardinality: 'finite' - }) - }); - } - toast.success(`Updated ${t.organization({ case: 'lower' })}`); - }, - onError: (error: Error) => { - toast.error('Something went wrong', { - description: error?.message || 'Failed to update' - }); - } - } - ); - - const { - reset, - register, - handleSubmit, - watch, - setValue, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(generalSchema) - }); - - const URL_PREFIX = window?.location?.host + '/'; - - useEffect(() => { - reset(organization); - }, [organization, reset]); - - async function onSubmit(data: FormData) { - if (!organization?.id) return; - - try { - const req = create(UpdateOrganizationRequestSchema, { - id: organization.id, - body: { - title: data.title, - name: data.name, - avatar: data.avatar - } - }); - await updateOrganization(req); - } catch (error: unknown) { - toast.error('Something went wrong', { - description: - error instanceof Error - ? error.message - : `Failed to update ${t.organization({ case: 'lower' })}` - }); - } - } - - return ( -
- - {isLoading ? ( - - - - - ) : ( - setValue('avatar', value)} - subText={`Pick a logo for your ${t.organization({ - case: 'lower' - })}.`} - initials={getInitials(organization?.title || organization?.name)} - disabled={!canUpdateWorkspace} - data-test-id="frontier-sdk-avatar-upload" - /> - )} - - - - - {isLoading ? ( - <> - - - - ) : ( - - )} - - - {isLoading ? ( - <> - - - - ) : ( - - )} - - {isLoading ? ( - - ) : ( - - - - )} - - - ); -}; - diff --git a/web/sdk/react/views/general/general-page.tsx b/web/sdk/react/views/general/general-page.tsx deleted file mode 100644 index 5873dd431..000000000 --- a/web/sdk/react/views/general/general-page.tsx +++ /dev/null @@ -1,127 +0,0 @@ -'use client'; - -import { useMemo, useState } from 'react'; -import { - Button, - Tooltip, - Separator, - Skeleton, - Text, - Flex -} from '@raystack/apsara'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { usePermissions } from '~/react/hooks/usePermissions'; -import { PERMISSIONS, shouldShowComponent } from '~/utils'; -import { GeneralOrganization } from './general-organization'; -import { AuthTooltipMessage } from '~/react/utils'; -import { useTerminology } from '~/react/hooks/useTerminology'; -import { PageHeader } from '~/react/components/common/page-header'; -import { DeleteOrganizationDialog } from './delete-organization-dialog'; -import sharedStyles from '../../components/organization/styles.module.css'; - -export interface GeneralPageProps { - onDeleteSuccess?: () => void; -} - -export function GeneralPage({ onDeleteSuccess }: GeneralPageProps = {}) { - const t = useTerminology(); - const { activeOrganization: organization, isActiveOrganizationLoading } = - useFrontier(); - - const resource = `app/organization:${organization?.id}`; - - const listOfPermissionsToCheck = useMemo(() => { - return [ - { - permission: PERMISSIONS.UpdatePermission, - resource: resource - }, - { - permission: PERMISSIONS.DeletePermission, - resource: resource - } - ]; - }, [resource]); - - const { permissions, isFetching: isPermissionsFetching } = usePermissions( - listOfPermissionsToCheck, - !!organization?.id - ); - - const { canUpdateWorkspace, canDeleteWorkspace } = useMemo(() => { - return { - canUpdateWorkspace: shouldShowComponent( - permissions, - `${PERMISSIONS.UpdatePermission}::${resource}` - ), - canDeleteWorkspace: shouldShowComponent( - permissions, - `${PERMISSIONS.DeletePermission}::${resource}` - ) - }; - }, [permissions, resource]); - - const isLoading = isActiveOrganizationLoading || isPermissionsFetching; - - const [showDeleteDialog, setShowDeleteDialog] = useState(false); - - return ( - - - - - - - - - - {isLoading ? ( - - ) : ( - - If you want to permanently delete this{' '} - {t.organization({ case: 'lower' })} and all of its data. - - )} - {isLoading ? ( - - ) : ( - - - - )} - - - - - - ); -} - diff --git a/web/sdk/react/views-new/general/general-view.module.css b/web/sdk/react/views/general/general-view.module.css similarity index 100% rename from web/sdk/react/views-new/general/general-view.module.css rename to web/sdk/react/views/general/general-view.module.css diff --git a/web/sdk/react/views-new/general/general-view.tsx b/web/sdk/react/views/general/general-view.tsx similarity index 99% rename from web/sdk/react/views-new/general/general-view.tsx rename to web/sdk/react/views/general/general-view.tsx index 80e7b7d45..2cffaa7e5 100644 --- a/web/sdk/react/views-new/general/general-view.tsx +++ b/web/sdk/react/views/general/general-view.tsx @@ -24,7 +24,7 @@ import { Field, Input, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useFrontier } from '../../contexts/FrontierContext'; import { usePermissions } from '../../hooks/usePermissions'; import { useTerminology } from '../../hooks/useTerminology'; diff --git a/web/sdk/react/views/general/general.module.css b/web/sdk/react/views/general/general.module.css deleted file mode 100644 index e396d0f3b..000000000 --- a/web/sdk/react/views/general/general.module.css +++ /dev/null @@ -1,52 +0,0 @@ -.profileDescription { - color: var(--rs-color-foreground-base-secondary); -} - -.separator { - margin: 32px 0; -} - -.deleteIcon { - cursor: pointer; -} - -.prefixInput { - position: relative; - border-radius: var(--rs-space-2); - padding: var(--rs-space-3); - background-color: var(--rs-color-background-base-primary); - border: 0.5px solid var(--rs-color-border-base-secondary); - color: var(--rs-color-foreground-base-primary); - display: flex; - align-items: center; - width: 100%; -} - -.prefixInput:focus-within { - border: 1px solid var(--rs-color-background-accent-primary-inverted); -} - -.prefixInput > input { - background-color: var(--rs-color-background-base-primary); - color: var(--rs-color-foreground-base-primary); - outline: none; - border: none; - width: 100%; - font-size: 13px; - line-height: 16px; -} - -.prefixInput > input:disabled { - cursor: not-allowed; - opacity: 0.6; - pointer-events: none; -} - -.overlay { - background-color: rgba(104, 112, 118, 0.5); -} - -.deleteFooter { - flex-direction: column; -} - diff --git a/web/sdk/react/views/general/index.ts b/web/sdk/react/views/general/index.ts index f18f55af0..d2d160404 100644 --- a/web/sdk/react/views/general/index.ts +++ b/web/sdk/react/views/general/index.ts @@ -1,8 +1,2 @@ -export { GeneralPage } from './general-page'; -export type { GeneralPageProps } from './general-page'; - -export { GeneralOrganization } from './general-organization'; -export type { GeneralOrganizationProps } from './general-organization'; - -export { DeleteOrganizationDialog } from './delete-organization-dialog'; -export type { DeleteOrganizationDialogProps } from './delete-organization-dialog'; +export { GeneralView } from './general-view'; +export type { GeneralViewProps } from './general-view'; diff --git a/web/sdk/react/views-new/members/components/invite-member-dialog.tsx b/web/sdk/react/views/members/components/invite-member-dialog.tsx similarity index 99% rename from web/sdk/react/views-new/members/components/invite-member-dialog.tsx rename to web/sdk/react/views/members/components/invite-member-dialog.tsx index 40995ad00..c704b7017 100644 --- a/web/sdk/react/views-new/members/components/invite-member-dialog.tsx +++ b/web/sdk/react/views/members/components/invite-member-dialog.tsx @@ -24,7 +24,7 @@ import { Field, TextArea, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useFrontier } from '../../../contexts/FrontierContext'; import { PERMISSIONS } from '../../../../utils'; import { handleConnectError } from '~/utils/error'; diff --git a/web/sdk/react/views-new/members/components/member-columns.module.css b/web/sdk/react/views/members/components/member-columns.module.css similarity index 100% rename from web/sdk/react/views-new/members/components/member-columns.module.css rename to web/sdk/react/views/members/components/member-columns.module.css diff --git a/web/sdk/react/views-new/members/components/member-columns.tsx b/web/sdk/react/views/members/components/member-columns.tsx similarity index 99% rename from web/sdk/react/views-new/members/components/member-columns.tsx rename to web/sdk/react/views/members/components/member-columns.tsx index fcc45a5e6..28124e69b 100644 --- a/web/sdk/react/views-new/members/components/member-columns.tsx +++ b/web/sdk/react/views/members/components/member-columns.tsx @@ -9,7 +9,7 @@ import { Menu, IconButton, DataTableColumnDef -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import type { Role } from '@raystack/proton/frontier'; import type { MemberWithInvite } from '~/react/hooks/useOrganizationMembers'; import { differenceWith, getInitials, isEqualById } from '~/utils'; diff --git a/web/sdk/react/views-new/members/components/remove-member-dialog.tsx b/web/sdk/react/views/members/components/remove-member-dialog.tsx similarity index 99% rename from web/sdk/react/views-new/members/components/remove-member-dialog.tsx rename to web/sdk/react/views/members/components/remove-member-dialog.tsx index b863e8799..c36784928 100644 --- a/web/sdk/react/views-new/members/components/remove-member-dialog.tsx +++ b/web/sdk/react/views/members/components/remove-member-dialog.tsx @@ -12,7 +12,7 @@ import { AlertDialog, Button, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { useFrontier } from '../../../contexts/FrontierContext'; import { useTerminology } from '../../../hooks/useTerminology'; import { handleConnectError } from '~/utils/error'; diff --git a/web/sdk/react/views-new/members/components/update-role-dialog.tsx b/web/sdk/react/views/members/components/update-role-dialog.tsx similarity index 99% rename from web/sdk/react/views-new/members/components/update-role-dialog.tsx rename to web/sdk/react/views/members/components/update-role-dialog.tsx index 5cf63a106..9c82ceed6 100644 --- a/web/sdk/react/views-new/members/components/update-role-dialog.tsx +++ b/web/sdk/react/views/members/components/update-role-dialog.tsx @@ -12,7 +12,7 @@ import { AlertDialog, Button, toastManager -} from '@raystack/apsara-v1'; +} from '@raystack/apsara'; import { handleConnectError } from '~/utils/error'; export type UpdateRolePayload = { memberId: string; role: Role }; diff --git a/web/sdk/react/views/members/index.ts b/web/sdk/react/views/members/index.ts index 14e1c5b2b..5ff94716e 100644 --- a/web/sdk/react/views/members/index.ts +++ b/web/sdk/react/views/members/index.ts @@ -1,8 +1,2 @@ -export { MembersPage } from './members-page'; -export type { MembersPageProps } from './members-page'; - -export { InviteMemberDialog } from './invite-member-dialog'; -export type { InviteMemberDialogProps } from './invite-member-dialog'; - -export { RemoveMemberDialog as MemberRemoveConfirmDialog } from './remove-member-dialog'; -export type { MemberRemoveConfirmDialogProps } from './remove-member-dialog'; +export { MembersView } from './members-view'; +export type { MembersViewProps } from './members-view'; diff --git a/web/sdk/react/views/members/invite-member-dialog.tsx b/web/sdk/react/views/members/invite-member-dialog.tsx deleted file mode 100644 index e6e2365cd..000000000 --- a/web/sdk/react/views/members/invite-member-dialog.tsx +++ /dev/null @@ -1,305 +0,0 @@ -import { - Button, - toast, - Skeleton, - Image, - Text, - Select, - Flex, - Dialog, - TextArea, - Label -} from '@raystack/apsara'; - -import { yupResolver } from '@hookform/resolvers/yup'; -import { useCallback, useMemo } from 'react'; -import { Controller, useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import cross from '~/react/assets/cross.svg'; -import { useFrontier } from '~/react/contexts/FrontierContext'; -import { PERMISSIONS } from '~/utils'; -import { useMutation, useQuery } from '@connectrpc/connect-query'; -import { - FrontierServiceQueries, - CreateOrganizationInvitationRequestSchema, - ListOrganizationRolesRequestSchema, - ListRolesRequestSchema, - ListOrganizationGroupsRequestSchema -} from '@raystack/proton/frontier'; -import { create } from '@bufbuild/protobuf'; -import { handleSelectValueChange } from '~/react/utils'; -import styles from '../../components/organization/organization.module.css'; -import { handleConnectError } from '~/utils/error'; - -const inviteSchema = yup.object({ - type: yup.string().required(), - team: yup.string(), - emails: yup.string().required() -}); - -type InviteSchemaType = yup.InferType; - -export interface InviteMemberDialogProps { - open: boolean; - onOpenChange: (value: boolean) => void; -} - -export const InviteMemberDialog = ({ - open, - onOpenChange -}: InviteMemberDialogProps) => { - const { - watch, - register, - control, - handleSubmit, - formState: { errors, isSubmitting } - } = useForm({ - resolver: yupResolver(inviteSchema) - }); - const { activeOrganization: organization } = useFrontier(); - - // Organization roles query - const { data: orgRolesData, isLoading: isOrgRolesLoading } = useQuery( - FrontierServiceQueries.listOrganizationRoles, - create(ListOrganizationRolesRequestSchema, { - orgId: organization?.id || '', - scopes: [PERMISSIONS.OrganizationNamespace] - }), - { - enabled: !!organization?.id - } - ); - - const orgRoles = useMemo(() => orgRolesData?.roles || [], [orgRolesData]); - - // Global roles query - const { data: globalRolesData, isLoading: isGlobalRolesLoading } = useQuery( - FrontierServiceQueries.listRoles, - create(ListRolesRequestSchema, { - scopes: [PERMISSIONS.OrganizationNamespace] - }), - { - enabled: !!organization?.id - } - ); - - const globalRoles = useMemo( - () => globalRolesData?.roles || [], - [globalRolesData] - ); - - // Organization groups query - const { data: teamsData, isLoading: isGroupsLoading } = useQuery( - FrontierServiceQueries.listOrganizationGroups, - create(ListOrganizationGroupsRequestSchema, { - orgId: organization?.id || '' - }), - { - enabled: !!organization?.id - } - ); - - const teams = useMemo(() => teamsData?.groups || [], [teamsData]); - - const isLoading = - isOrgRolesLoading || isGlobalRolesLoading || isGroupsLoading; - - const roles = useMemo( - () => [...(globalRoles || []), ...(orgRoles || [])], - [globalRoles, orgRoles] - ); - - const { mutateAsync: createInvitation } = useMutation( - FrontierServiceQueries.createOrganizationInvitation, - { - onSuccess: () => { - toast.success('User(s) invited'); - onOpenChange(false); - } - } - ); - - const values = watch(['emails', 'type']); - - const onSubmit = useCallback( - async ({ emails, type, team }: InviteSchemaType) => { - const emailList = emails - .split(',') - .map(e => e.trim()) - .filter(str => str.length > 0); - - if (!organization?.id) return; - if (!emailList.length) return; - if (!type) return; - - try { - const req = create(CreateOrganizationInvitationRequestSchema, { - orgId: organization.id, - userIds: emailList, - groupIds: team ? [team] : undefined, - roleIds: [type] - }); - await createInvitation(req); - } catch (error) { - handleConnectError(error, { - AlreadyExists: () => toast.error('Invitation already exists'), - InvalidArgument: (err) => toast.error('Invalid input', { description: err.message }), - PermissionDenied: () => toast.error("You don't have permission to perform this action"), - Default: (err) => toast.error('Something went wrong', { description: err.message }), - }); - } - }, - [createInvitation, organization?.id] - ); - - const isDisabled = useMemo(() => { - const [emails, type] = values; - const emailList = - emails - ?.split(',') - .map((e: string) => e.trim()) - .filter(str => str.length > 0) || []; - return emailList.length <= 0 || !type || isSubmitting; - }, [isSubmitting, values]); - - return ( - - - - - - Invite people - - cross onOpenChange(false)} - data-test-id="frontier-sdk-invite-member-close-btn" - /> - - - -
- - {isLoading ? ( - - ) : ( -