├── src ├── hooks │ ├── useDebounce.ts │ ├── usePagePosition.tsx │ ├── use-mobile.tsx │ ├── useUser.tsx │ ├── UserContext.tsx │ └── useBreadcrumbs.ts ├── pages │ ├── error-demo │ │ └── ErrorDemo.tsx │ ├── error │ │ ├── index.ts │ │ └── ErrorPage.tsx │ ├── settings │ │ └── index.ts │ ├── home │ │ └── index.ts │ ├── webhooks │ │ └── index.ts │ ├── developer │ │ └── index.ts │ ├── onboarding │ │ └── index.ts │ ├── usage │ │ └── index.ts │ ├── customer │ │ ├── creditnotes │ │ │ └── CreditNoteDetailsPage.tsx │ │ └── payments │ │ │ ├── PaymentPage.tsx │ │ │ └── PaymentList.tsx │ ├── product-catalog │ │ ├── addons │ │ │ └── AddonCharges.tsx │ │ ├── cost-sheets │ │ │ └── CostSheetCharges.tsx │ │ ├── plans │ │ │ └── AddCharges.tsx │ │ └── index.ts │ ├── auth │ │ └── index.ts │ ├── index.ts │ └── insights-tools │ │ ├── index.ts │ │ └── exports │ │ └── TaskRunsPage.tsx ├── components │ ├── atoms │ │ ├── Chip │ │ │ └── index.ts │ │ ├── Page │ │ │ ├── index.ts │ │ │ └── Page.tsx │ │ ├── Dialog │ │ │ ├── index.ts │ │ │ └── Dialog.tsx │ │ ├── Divider │ │ │ ├── index.ts │ │ │ └── Divider.tsx │ │ ├── Input │ │ │ ├── index.ts │ │ │ └── Input.stories.tsx │ │ ├── Label │ │ │ ├── index.ts │ │ │ └── Label.tsx │ │ ├── Modal │ │ │ ├── index.ts │ │ │ └── Modal.tsx │ │ ├── Sheet │ │ │ └── index.ts │ │ ├── Spacer │ │ │ ├── index.ts │ │ │ └── Spacer.tsx │ │ ├── Spinner │ │ │ ├── index.ts │ │ │ └── Spinner.tsx │ │ ├── Stepper │ │ │ └── index.ts │ │ ├── Toggle │ │ │ ├── index.ts │ │ │ └── Toggle.tsx │ │ ├── Tooltip │ │ │ ├── index.ts │ │ │ └── Tooltip.tsx │ │ ├── Checkbox │ │ │ └── index.ts │ │ ├── CodeBlock │ │ │ ├── index.ts │ │ │ └── CodeBlock.tsx │ │ ├── Progress │ │ │ ├── index.ts │ │ │ └── Progress.tsx │ │ ├── Textarea │ │ │ └── index.ts │ │ ├── ActionButton │ │ │ └── index.ts │ │ ├── Card │ │ │ └── index.ts │ │ ├── CodePreview │ │ │ └── index.ts │ │ ├── ComingSoon │ │ │ ├── index.ts │ │ │ └── ComingSoon.tsx │ │ ├── DatePicker │ │ │ └── index.ts │ │ ├── FormHeader │ │ │ └── index.ts │ │ ├── MultiSelect │ │ │ └── index.ts │ │ ├── NoDataCard │ │ │ ├── index.ts │ │ │ └── NoDataCard.tsx │ │ ├── DateTimePicker │ │ │ └── index.ts │ │ ├── MultichipInput │ │ │ └── index.ts │ │ ├── SectionHeader │ │ │ └── index.ts │ │ ├── SelectFeature │ │ │ └── index.ts │ │ ├── DateRangePicker │ │ │ └── index.ts │ │ ├── DecimalUsageInput │ │ │ └── index.ts │ │ ├── ShortPagination │ │ │ └── index.ts │ │ ├── FeatureMultiSelect │ │ │ └── index.ts │ │ ├── PaymentUrlSuccessDialog │ │ │ └── index.ts │ │ ├── Loader │ │ │ └── index.ts │ │ ├── RadioGroup │ │ │ └── index.ts │ │ ├── Combobox │ │ │ └── index.ts │ │ ├── CheckboxRadioGroup │ │ │ └── index.ts │ │ ├── Button │ │ │ ├── index.ts │ │ │ └── AddButton.tsx │ │ ├── ErrorBoundary │ │ │ └── index.ts │ │ └── Select │ │ │ └── index.ts │ ├── molecules │ │ ├── DebugMenu │ │ │ └── index.ts │ │ ├── Events │ │ │ └── index.ts │ │ ├── Pagination │ │ │ └── index.ts │ │ ├── PlanDrawer │ │ │ └── index.ts │ │ ├── PlansTable │ │ │ └── index.ts │ │ ├── AddonDrawer │ │ │ └── index.ts │ │ ├── BreadCrumbs │ │ │ └── index.ts │ │ ├── CouponDrawer │ │ │ └── index.ts │ │ ├── CouponModal │ │ │ └── index.ts │ │ ├── CouponTable │ │ │ └── index.ts │ │ ├── FeatureTable │ │ │ └── index.ts │ │ ├── GroupDrawer │ │ │ └── index.ts │ │ ├── GroupsTable │ │ │ └── index.ts │ │ ├── ApiDocs │ │ │ └── index.ts │ │ ├── ForceRunDrawer │ │ │ └── index.ts │ │ ├── InfiniteScroll │ │ │ └── index.ts │ │ ├── LineItemCoupon │ │ │ └── index.ts │ │ ├── SaveCardModal │ │ │ └── index.ts │ │ ├── SecretKeyDrawer │ │ │ └── index.ts │ │ ├── TierBreakdown │ │ │ └── index.ts │ │ ├── Wallet │ │ │ └── index.ts │ │ ├── WalletDebitCard │ │ │ └── index.ts │ │ ├── WalletTopupCard │ │ │ └── index.ts │ │ ├── AppliedTaxesTable │ │ │ └── index.ts │ │ ├── ImportFileDrawer │ │ │ └── index.ts │ │ ├── UpdatePriceDialog │ │ │ └── index.ts │ │ ├── WalletAlertDialog │ │ │ └── index.ts │ │ ├── AddEntitlementDrawer │ │ │ └── index.ts │ │ ├── CustomerUsageTable │ │ │ └── index.ts │ │ ├── EnvironmentSelector │ │ │ └── index.ts │ │ ├── InvoicePaymentsTable │ │ │ └── index.ts │ │ ├── PriceOverrideDialog │ │ │ └── index.ts │ │ ├── RecordPaymentTopup │ │ │ └── index.ts │ │ ├── ServiceAccountDrawer │ │ │ └── index.ts │ │ ├── TaxAssociationDialog │ │ │ └── index.ts │ │ ├── TaxAssociationTable │ │ │ └── index.ts │ │ ├── TerminateWalletModal │ │ │ └── index.ts │ │ ├── CommitmentConfigDialog │ │ │ └── index.ts │ │ ├── MetadataModal │ │ │ └── index.ts │ │ ├── NomodConnectionDrawer │ │ │ └── index.ts │ │ ├── StripeConnectionDrawer │ │ │ └── index.ts │ │ ├── TerminateLineItemModal │ │ │ └── index.ts │ │ ├── ChargeValueCell │ │ │ └── index.ts │ │ ├── ChargebeeConnectionDrawer │ │ │ └── index.ts │ │ ├── HubSpotConnectionDrawer │ │ │ └── index.ts │ │ ├── PremiumFeature │ │ │ └── index.ts │ │ ├── RazorpayConnectionDrawer │ │ │ └── index.ts │ │ ├── RolloutChargesModal │ │ │ └── index.ts │ │ ├── SubscriptionTable │ │ │ └── index.ts │ │ ├── DocsDrawer │ │ │ └── index.ts │ │ ├── FeatureAlertDialog │ │ │ └── index.ts │ │ ├── InvoiceCreditLineItemTable │ │ │ └── index.ts │ │ ├── SubscriptionTaxAssociationTable │ │ │ └── index.ts │ │ ├── CustomPopover │ │ │ └── index.ts │ │ ├── EventFilter │ │ │ └── index.ts │ │ ├── SubscriptionDiscountTable │ │ │ └── index.ts │ │ ├── PricingCard │ │ │ └── index.ts │ │ ├── Sidebar │ │ │ ├── index.ts │ │ │ └── UserProfile.tsx │ │ ├── Tabs │ │ │ ├── index.ts │ │ │ └── CustomTabs.tsx │ │ ├── DetailsCard │ │ │ └── index.ts │ │ ├── DropdownMenu │ │ │ └── index.ts │ │ ├── AddonTable │ │ │ └── index.ts │ │ ├── TerminatePriceModal │ │ │ └── index.ts │ │ ├── SubscriptionEntitlementsSection │ │ │ └── index.ts │ │ ├── RectangleRadiogroup │ │ │ └── index.ts │ │ ├── CreditNoteTable │ │ │ └── index.ts │ │ ├── InvoiceLineItemTable │ │ │ └── index.ts │ │ ├── EntitlementOverrides │ │ │ └── index.ts │ │ ├── Table │ │ │ ├── index.ts │ │ │ ├── RedirectCell.tsx │ │ │ └── TooltipCell.tsx │ │ ├── Dashboard │ │ │ └── index.ts │ │ ├── CreditGrant │ │ │ └── index.ts │ │ ├── Customer │ │ │ └── index.ts │ │ ├── InvoiceTable │ │ │ ├── index.ts │ │ │ └── CustomerInvoiceTable.tsx │ │ ├── QueryBuilder │ │ │ └── index.ts │ │ ├── CustomerSubscription │ │ │ └── SubscriptionPauseWarning.tsx │ │ └── MetricCard.tsx │ ├── organisms │ │ ├── EmptyPage │ │ │ └── index.ts │ │ ├── PlanPriceTable │ │ │ └── index.ts │ │ ├── EntityChargesPage │ │ │ └── index.ts │ │ ├── PlanForm │ │ │ └── index.ts │ │ ├── index.ts │ │ └── Subscription │ │ │ ├── index.ts │ │ │ └── UsageTable.tsx │ └── ui │ │ ├── skeleton.tsx │ │ ├── collapsible.tsx │ │ ├── textarea.tsx │ │ ├── label.tsx │ │ ├── separator.tsx │ │ ├── progress.tsx │ │ ├── input.tsx │ │ ├── slider.tsx │ │ ├── checkbox.tsx │ │ ├── badge.tsx │ │ ├── tooltip.tsx │ │ ├── switch.tsx │ │ ├── popover.tsx │ │ └── scroll-area.tsx ├── types │ ├── common │ │ ├── Table.ts │ │ ├── BaseCadence.ts │ │ ├── Filters.ts │ │ ├── Environment.ts │ │ ├── Coupon.ts │ │ └── index.ts │ ├── dto │ │ ├── webhook.ts │ │ ├── Auth.ts │ │ ├── UserApi.ts │ │ ├── base.ts │ │ ├── Testimonial.ts │ │ ├── Environment.ts │ │ ├── Integration.ts │ │ ├── LineItemCommitmentConfig.ts │ │ ├── User.ts │ │ ├── Tenant.ts │ │ ├── SecretApi.ts │ │ ├── Group.ts │ │ ├── Payment.ts │ │ ├── Coupon.ts │ │ ├── CostSheet.ts │ │ ├── CreditGrantApplication.ts │ │ ├── Meter.ts │ │ ├── CreditNote.ts │ │ └── Task.ts │ ├── index.ts │ ├── formatters │ │ ├── index.ts │ │ ├── BaseEntity.ts │ │ └── Feature.ts │ ├── font.d.ts │ └── enums │ │ ├── ChargebeeWebhookEvents.ts │ │ ├── QuickBooksWebhookEvents.ts │ │ ├── RazorpayWebhookEvents.ts │ │ └── NomodWebhookEvents.ts ├── vite-env.d.ts ├── utils │ ├── helpers │ │ ├── index.ts │ │ ├── wallet.ts │ │ └── coupons.ts │ ├── index.ts │ └── common │ │ ├── format_chips.ts │ │ ├── format_cadence_chip.ts │ │ ├── format_number.ts │ │ ├── api_helper.ts │ │ ├── index.ts │ │ ├── format_coupon_name.ts │ │ └── credit_grant_helpers.ts ├── models │ ├── Pagination.ts │ ├── Event.ts │ ├── Environment.ts │ ├── Integration.ts │ ├── CostSheet.ts │ ├── Addon.ts │ ├── base.ts │ ├── Group.ts │ ├── Plan.ts │ ├── Customer.ts │ ├── CustomerEntitlement.ts │ ├── User.ts │ ├── Coupon.ts │ ├── expand.ts │ ├── SecretKey.ts │ ├── ImportTask.ts │ ├── Connection.ts │ ├── Tenant.ts │ ├── WalletTransaction.ts │ ├── Entitlement.ts │ ├── ScheduledTask.ts │ ├── Feature.ts │ ├── Meter.ts │ ├── CustomerUsage.ts │ ├── WalletBalance.ts │ ├── CreditGrant.ts │ ├── Payment.ts │ └── Analytics.ts ├── assets │ └── fonts │ │ └── qanelas │ │ ├── QanelasBlack.otf │ │ ├── QanelasBold.otf │ │ ├── QanelasHeavy.otf │ │ ├── QanelasLight.otf │ │ ├── QanelasThin.otf │ │ ├── QanelasMedium.otf │ │ ├── QanelasRegular.otf │ │ ├── QanelasBoldItalic.otf │ │ ├── QanelasExtraBold.otf │ │ ├── QanelasSemiBold.otf │ │ ├── QanelasThinItalic.otf │ │ ├── QanelasUltraLight.otf │ │ ├── QanelasBlackItalic.otf │ │ ├── QanelasHeavyItalic.otf │ │ ├── QanelasLightItalic.otf │ │ ├── QanelasMediumItalic.otf │ │ ├── QanelasExtraBoldItalic.otf │ │ ├── QanelasRegularItalic.otf │ │ ├── QanelasSemiBoldItalic.otf │ │ └── QanelasUltraLightItalic.otf ├── store │ ├── index.ts │ └── useApiDocsStore.ts ├── lib │ ├── utils.ts │ └── sizing.ts ├── core │ ├── services │ │ ├── vercel │ │ │ └── vercel.tsx │ │ ├── sentry │ │ │ └── SentryProvider.tsx │ │ ├── intercom │ │ │ └── index.css │ │ ├── posthog │ │ │ └── PosthogProvider.tsx │ │ └── supbase │ │ │ └── config.ts │ ├── axios │ │ └── types.ts │ └── auth │ │ ├── AuthProvider.tsx │ │ └── AuthService.ts ├── api │ ├── WebhookApi.ts │ ├── RbacApi.ts │ ├── TenantApi.ts │ ├── IntegrationsApi.ts │ ├── AuthApi.ts │ ├── CreditGrantApi.ts │ ├── EnvironmentApi.ts │ ├── CouponApi.ts │ ├── MeterApi.ts │ ├── ConnectionApi.ts │ ├── SecretKeysApi.ts │ ├── index.ts │ └── ExportRunApi.ts ├── tests │ └── setup.ts ├── constants │ ├── index.ts │ └── loading_quotes.ts ├── main.tsx ├── context │ └── DocsContext.tsx └── App.tsx ├── docs ├── search-filter-implementation.md └── voidInvoice.md ├── .prettierignore ├── public ├── meta.json ├── newlogobrowser.png ├── assets │ ├── logo │ │ ├── logo.png │ │ └── chargebee.png │ ├── png │ │ ├── aftershoot.png │ │ └── ic_login_bg.png │ ├── company-founders │ │ ├── clueso.png │ │ ├── chaabi.webp │ │ ├── krutrim.png │ │ ├── publive.webp │ │ ├── verniq.webp │ │ ├── aftershoot.png │ │ ├── simplismart.png │ │ ├── truffleai.png │ │ ├── wizcommerce.png │ │ ├── simplismart.webp │ │ ├── wizcommerce.webp │ │ ├── 1732115195410.jpeg │ │ └── 1747891553125.jpeg │ ├── company-logo │ │ ├── Clueso Logo.png │ │ ├── aftershoot.webp │ │ ├── krutrim logo.png │ │ ├── Truffle AI Logo.png │ │ ├── aftershoot copy.png │ │ ├── aftershoot copy.tiff │ │ ├── Y_Combinator_logo.svg.png │ │ └── quickbooks.svg │ └── csv │ │ └── sample.csv ├── ic_rounded_flexprice.svg └── favicon.svg ├── .husky └── pre-commit ├── assets ├── open-arch.jpg ├── open-arch.png ├── struggle.png ├── flexprice_logo.png └── complex-iterations.png ├── vite.config.d.ts ├── postcss.config.js ├── vercel.json ├── nginx.conf ├── .storybook ├── preview.ts └── main.ts ├── docker-compose.yml ├── tsconfig.app.json ├── index.html ├── scripts └── generate-meta.js ├── Dockerfile ├── .dockerignore ├── nginx └── nginx.conf ├── components.json ├── SECURITY.md ├── .prettierrc.cjs ├── vite.config.ts ├── .gitignore ├── vitest.config.ts ├── vite.config.js ├── tsconfig.node.json ├── .env.example ├── eslint.config.js ├── tsconfig.json ├── setup.ps1 └── .github └── workflows ├── demo.yaml ├── staging.yaml └── production.yaml /src/hooks/useDebounce.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/error-demo/ErrorDemo.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/search-filter-implementation.md: -------------------------------------------------------------------------------- 1 | 1. -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Ignore artifacts: 4 | build -------------------------------------------------------------------------------- /public/meta.json: -------------------------------------------------------------------------------- 1 | {"versionId":"1a7422cf6447dc9fcdfebd51e59de791f875c086"} -------------------------------------------------------------------------------- /src/components/atoms/Chip/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Chip'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Page/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Page'; 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npm run format 2 | npx lint-staged 3 | npm run build 4 | -------------------------------------------------------------------------------- /src/components/atoms/Dialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Dialog'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Divider/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Divider'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Input/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Input'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Label/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Label'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Modal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Modal'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Sheet/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Sheet'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Spacer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Spacer'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Spinner/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Spinner'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Stepper/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Stepper'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Toggle/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Toggle'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Tooltip/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Tooltip'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Checkbox'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/CodeBlock/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CodeBlock'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Progress/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Progress'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Textarea/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Textarea'; 2 | -------------------------------------------------------------------------------- /src/pages/error/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ErrorPage } from './ErrorPage'; 2 | -------------------------------------------------------------------------------- /src/pages/settings/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Billing } from './Billing'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/ActionButton/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ActionButton'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/Card/index.ts: -------------------------------------------------------------------------------- 1 | export { default, CardHeader } from './Card'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/CodePreview/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CodePreview'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/ComingSoon/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ComingSoon'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/DatePicker/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DatePicker'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/FormHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './FormHeader'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/MultiSelect/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './MultiSelect'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/NoDataCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NoDataCard'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/DebugMenu/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DebugMenu'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/Events/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EventsTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/Pagination/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Pagination'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/PlanDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PlanDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/PlansTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PlansTable'; 2 | -------------------------------------------------------------------------------- /src/components/organisms/EmptyPage/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EmptyPage'; 2 | -------------------------------------------------------------------------------- /src/pages/home/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DashboardPage } from './DashboardPage'; 2 | -------------------------------------------------------------------------------- /src/types/common/Table.ts: -------------------------------------------------------------------------------- 1 | export type { ColumnData } from '@/components/molecules'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/DateTimePicker/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DateTimePicker'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/MultichipInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './MultiChipInput'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/SectionHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SectionHeader'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/SelectFeature/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SelectFeature'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/AddonDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './AddonDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/BreadCrumbs/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './BreadCrumbs'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/CouponDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CouponDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/CouponModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CouponModal'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/CouponTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CouponTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/FeatureTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './FeatureTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/GroupDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './GroupDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/GroupsTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './GroupsTable'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/DateRangePicker/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DateRangePicker'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/DecimalUsageInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DecimalUsageInput'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/ShortPagination/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ShortPagination'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/ApiDocs/index.ts: -------------------------------------------------------------------------------- 1 | export { default, ApiDocsContent } from './ApiDocs'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/ForceRunDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ForceRunDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/InfiniteScroll/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InfiniteScroll'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/LineItemCoupon/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LineItemCoupon'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/SaveCardModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SaveCardModal'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/SecretKeyDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SecretKeyDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/TierBreakdown/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TierBreakdown'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/Wallet/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './WalletTransactionsTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/WalletDebitCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './WalletDebitCard'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/WalletTopupCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './WalletTopupCard'; 2 | -------------------------------------------------------------------------------- /src/components/organisms/PlanPriceTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PlanPriceTable'; 2 | -------------------------------------------------------------------------------- /src/pages/webhooks/index.ts: -------------------------------------------------------------------------------- 1 | export { default as WebhookDashboard } from './WebhookDashboard'; 2 | -------------------------------------------------------------------------------- /assets/open-arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/assets/open-arch.jpg -------------------------------------------------------------------------------- /assets/open-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/assets/open-arch.png -------------------------------------------------------------------------------- /assets/struggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/assets/struggle.png -------------------------------------------------------------------------------- /src/components/atoms/FeatureMultiSelect/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './FeatureMultiSelect'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/AppliedTaxesTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './AppliedTaxesTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/ImportFileDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ImportFileDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/UpdatePriceDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './UpdatePriceDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/WalletAlertDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './WalletAlertDialog'; 2 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare const __APP_VERSION__: string; 3 | -------------------------------------------------------------------------------- /vite.config.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vite').UserConfig; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /src/components/molecules/AddEntitlementDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './AddEntitlementDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/CustomerUsageTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CustomerUsageTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/EnvironmentSelector/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EnvironmentSelector'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/InvoicePaymentsTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InvoicePaymentsTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/PriceOverrideDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PriceOverrideDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/RecordPaymentTopup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RecordPaymentTopup'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/ServiceAccountDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ServiceAccountDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/TaxAssociationDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TaxAssociationDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/TaxAssociationTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TaxAssociationTable'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/TerminateWalletModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TerminateWalletModal'; 2 | -------------------------------------------------------------------------------- /assets/flexprice_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/assets/flexprice_logo.png -------------------------------------------------------------------------------- /public/newlogobrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/newlogobrowser.png -------------------------------------------------------------------------------- /src/components/atoms/PaymentUrlSuccessDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PaymentUrlSuccessDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/CommitmentConfigDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CommitmentConfigDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/MetadataModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default as MetadataModal } from './MetadataModal'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/NomodConnectionDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NomodConnectionDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/StripeConnectionDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './StripeConnectionDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/TerminateLineItemModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TerminateLineItemModal'; 2 | -------------------------------------------------------------------------------- /public/assets/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/logo/logo.png -------------------------------------------------------------------------------- /src/components/molecules/ChargeValueCell/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ChargeValueCell } from './ChargeValueCell'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/ChargebeeConnectionDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './ChargebeeConnectionDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/HubSpotConnectionDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './HubSpotConnectionDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/PremiumFeature/index.ts: -------------------------------------------------------------------------------- 1 | export { default, PremiumFeatureTag } from './PremiumFeature'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/RazorpayConnectionDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RazorpayConnectionDrawer'; 2 | -------------------------------------------------------------------------------- /assets/complex-iterations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/assets/complex-iterations.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/components/atoms/Loader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Loader'; 2 | export { PageLoader } from './Loader'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/RolloutChargesModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default, RolloutOption } from './RolloutChargesModal'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/SubscriptionTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SubscriptionTable } from './SubscriptionTable'; 2 | -------------------------------------------------------------------------------- /src/utils/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './coupons'; 2 | export * from './subscription'; 3 | export * from './wallet'; 4 | -------------------------------------------------------------------------------- /public/assets/logo/chargebee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/logo/chargebee.png -------------------------------------------------------------------------------- /public/assets/png/aftershoot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/png/aftershoot.png -------------------------------------------------------------------------------- /public/assets/png/ic_login_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/png/ic_login_bg.png -------------------------------------------------------------------------------- /src/components/molecules/DocsDrawer/index.ts: -------------------------------------------------------------------------------- 1 | export { default, SnippetBlock, type SupportedLanguage } from './DocsDrawer'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/FeatureAlertDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FeatureAlertDialog } from './FeatureAlertDialog'; 2 | -------------------------------------------------------------------------------- /src/components/molecules/InvoiceCreditLineItemTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InvoiceCreditLineItemTable.tsx'; 2 | -------------------------------------------------------------------------------- /src/models/Pagination.ts: -------------------------------------------------------------------------------- 1 | export interface Pagination { 2 | offset?: number; 3 | limit?: number; 4 | total?: number; 5 | } 6 | -------------------------------------------------------------------------------- /src/types/dto/webhook.ts: -------------------------------------------------------------------------------- 1 | export interface WebhookDashboardResponse { 2 | url: string; 3 | svix_enabled: boolean; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/molecules/SubscriptionTaxAssociationTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SubscriptionTaxAssociationTable'; 2 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | // Common utilities 2 | export * from './common'; 3 | 4 | // Helper utilities 5 | export * from './helpers'; 6 | -------------------------------------------------------------------------------- /src/components/molecules/CustomPopover/index.ts: -------------------------------------------------------------------------------- 1 | import CustomPopover from './CustomPopover'; 2 | 3 | export default CustomPopover; 4 | -------------------------------------------------------------------------------- /public/assets/company-founders/clueso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/clueso.png -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasBlack.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasBlack.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasBold.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasHeavy.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasHeavy.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasLight.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasThin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasThin.otf -------------------------------------------------------------------------------- /src/components/atoms/RadioGroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RadioGroup'; 2 | export type { RadioMenuItem } from './RadioGroup'; 3 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | export { useApiDocsStore } from './useApiDocsStore'; 2 | export { useBreadcrumbsStore } from './useBreadcrumbsStore'; 3 | -------------------------------------------------------------------------------- /src/types/common/BaseCadence.ts: -------------------------------------------------------------------------------- 1 | export enum CadenceStatus { 2 | ONCE = 'once', 3 | REPEAT = 'repeat', 4 | FOREVER = 'forever', 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/company-founders/chaabi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/chaabi.webp -------------------------------------------------------------------------------- /public/assets/company-founders/krutrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/krutrim.png -------------------------------------------------------------------------------- /public/assets/company-founders/publive.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/publive.webp -------------------------------------------------------------------------------- /public/assets/company-founders/verniq.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/verniq.webp -------------------------------------------------------------------------------- /public/assets/company-logo/Clueso Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/Clueso Logo.png -------------------------------------------------------------------------------- /public/assets/company-logo/aftershoot.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/aftershoot.webp -------------------------------------------------------------------------------- /public/assets/company-logo/krutrim logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/krutrim logo.png -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasMedium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasMedium.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasRegular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasRegular.otf -------------------------------------------------------------------------------- /src/components/molecules/EventFilter/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EventFilter'; 2 | export type { EventFilterData } from './EventFilter'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/SubscriptionDiscountTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SubscriptionDiscountTable } from './SubscriptionDiscountTable'; 2 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { 4 | "source": "/(.*)", 5 | "destination": "/" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /public/assets/company-founders/aftershoot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/aftershoot.png -------------------------------------------------------------------------------- /public/assets/company-founders/simplismart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/simplismart.png -------------------------------------------------------------------------------- /public/assets/company-founders/truffleai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/truffleai.png -------------------------------------------------------------------------------- /public/assets/company-founders/wizcommerce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/wizcommerce.png -------------------------------------------------------------------------------- /public/assets/company-logo/Truffle AI Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/Truffle AI Logo.png -------------------------------------------------------------------------------- /public/assets/company-logo/aftershoot copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/aftershoot copy.png -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasBoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasBoldItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasExtraBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasExtraBold.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasSemiBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasSemiBold.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasThinItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasThinItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasUltraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasUltraLight.otf -------------------------------------------------------------------------------- /src/components/molecules/PricingCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './PricingCard'; 2 | export type { PricingCardProps } from './PricingCard'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/Sidebar/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Sidebar } from './Sidebar'; 2 | export { default as SidbarMenu } from './SidebarMenu'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/Tabs/index.ts: -------------------------------------------------------------------------------- 1 | export { default as CustomTabs } from './CustomTabs'; 2 | export { default as FlatTabs } from './FlatTabs'; 3 | -------------------------------------------------------------------------------- /public/assets/company-founders/simplismart.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/simplismart.webp -------------------------------------------------------------------------------- /public/assets/company-founders/wizcommerce.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/wizcommerce.webp -------------------------------------------------------------------------------- /public/assets/company-logo/aftershoot copy.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/aftershoot copy.tiff -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasBlackItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasBlackItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasHeavyItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasHeavyItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasLightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasLightItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasMediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasMediumItalic.otf -------------------------------------------------------------------------------- /src/components/molecules/DetailsCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DetailsCard } from './DetailsCard'; 2 | export type { Detail } from './DetailsCard'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/DropdownMenu/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './DropdownMenu'; 2 | export type { DropdownMenuOption } from './DropdownMenu'; 3 | -------------------------------------------------------------------------------- /src/components/organisms/EntityChargesPage/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './EntityChargesPage'; 2 | export { ENTITY_TYPE } from './EntityChargesPage'; 3 | -------------------------------------------------------------------------------- /public/assets/company-founders/1732115195410.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/1732115195410.jpeg -------------------------------------------------------------------------------- /public/assets/company-founders/1747891553125.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-founders/1747891553125.jpeg -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasExtraBoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasExtraBoldItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasRegularItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasRegularItalic.otf -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasSemiBoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasSemiBoldItalic.otf -------------------------------------------------------------------------------- /src/components/atoms/Combobox/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Combobox } from './Combobox'; 2 | export type { ComboboxOption, ComboboxProps } from './Combobox'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/AddonTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default as AddonTable } from './AddonTable'; 2 | export { default as AddonModal } from './AddonModal'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/TerminatePriceModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './TerminatePriceModal'; 2 | export { SyncOption } from './TerminatePriceModal'; 3 | -------------------------------------------------------------------------------- /src/pages/developer/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DeveloperPage } from './developer'; 2 | export { default as ServiceAccountsPage } from './ServiceAccounts'; 3 | -------------------------------------------------------------------------------- /public/assets/company-logo/Y_Combinator_logo.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/public/assets/company-logo/Y_Combinator_logo.svg.png -------------------------------------------------------------------------------- /src/assets/fonts/qanelas/QanelasUltraLightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flexprice/flexprice-front/HEAD/src/assets/fonts/qanelas/QanelasUltraLightItalic.otf -------------------------------------------------------------------------------- /src/components/molecules/SubscriptionEntitlementsSection/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SubscriptionEntitlementsSection } from './SubscriptionEntitlementsSection'; 2 | -------------------------------------------------------------------------------- /src/components/atoms/CheckboxRadioGroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './CheckboxRadioGroup'; 2 | export type { CheckboxRadioGroupItem } from './CheckboxRadioGroup'; 3 | -------------------------------------------------------------------------------- /src/types/common/Filters.ts: -------------------------------------------------------------------------------- 1 | export interface Filters { 2 | expand?: string; 3 | limit?: number; 4 | offset?: number; 5 | order?: string; 6 | sort?: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | // Common types 2 | export * from './common'; 3 | 4 | // DTO types 5 | export * from './dto'; 6 | 7 | // Formatters 8 | export * from './formatters'; 9 | -------------------------------------------------------------------------------- /src/components/molecules/RectangleRadiogroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './RectangleRadiogroup'; 2 | export type { RectangleRadiogroupOption } from './RectangleRadiogroup'; 3 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 3000; 3 | location / { 4 | root /usr/share/nginx/html; 5 | index index.html; 6 | try_files $uri $uri/ /index.html; 7 | } 8 | } -------------------------------------------------------------------------------- /src/components/atoms/Button/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Button } from './Button'; 2 | export { default as AddButton } from './AddButton'; 3 | export type { ButtonProps } from './Button'; 4 | -------------------------------------------------------------------------------- /src/components/atoms/ErrorBoundary/index.ts: -------------------------------------------------------------------------------- 1 | export { ErrorBoundary, ErrorFallback, RouterErrorElement } from './ErrorBoundary'; 2 | export { ErrorBoundary as default } from './ErrorBoundary'; 3 | -------------------------------------------------------------------------------- /src/components/molecules/CreditNoteTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default as CreditNoteTable } from './CreditNoteTable'; 2 | export { default as CreditNoteLineItemTable } from './CreditNoteLineItemTable'; 3 | -------------------------------------------------------------------------------- /public/assets/csv/sample.csv: -------------------------------------------------------------------------------- 1 | event_name,external_customer_id,event_id,timestamp,source 2 | authentication,cus_001,event_001,2025-02-14T10:30:00Z,Web 3 | sign_up,cus_002,event_001,2025-02-14T11:00:00Z,Mobile -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /src/components/molecules/InvoiceLineItemTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InvoiceLineItemTable'; 2 | export { default as SubscriptionPreviewLineItemTable } from './SubscriptionPreviewLineItemTable'; 3 | -------------------------------------------------------------------------------- /src/pages/onboarding/index.ts: -------------------------------------------------------------------------------- 1 | export { default as OnboardingPage } from './onboarding'; 2 | export type { TutorialItem } from './onboarding'; 3 | export { default as OnboardingTenant } from './OnboardingTenant'; 4 | -------------------------------------------------------------------------------- /src/components/molecules/EntitlementOverrides/index.ts: -------------------------------------------------------------------------------- 1 | export { default as EntitlementOverridesTable } from './EntitlementOverridesTable'; 2 | export { default as EditEntitlementDrawer } from './EditEntitlementDrawer'; 3 | -------------------------------------------------------------------------------- /src/core/services/vercel/vercel.tsx: -------------------------------------------------------------------------------- 1 | import { SpeedInsights } from '@vercel/speed-insights/react'; 2 | 3 | const VercelSpeedInsights = () => { 4 | return ; 5 | }; 6 | 7 | export default VercelSpeedInsights; 8 | -------------------------------------------------------------------------------- /src/types/formatters/index.ts: -------------------------------------------------------------------------------- 1 | export { formatMeterUsageResetPeriodToDisplay } from './Feature'; 2 | export { sanitizeFilterConditions, sanitizeSortConditions } from './QueryBuilder'; 3 | export type { TypedBackendFilter } from './QueryBuilder'; 4 | -------------------------------------------------------------------------------- /src/types/common/Environment.ts: -------------------------------------------------------------------------------- 1 | export enum NodeEnv { 2 | LOCAL = 'local', 3 | DEV = 'development', 4 | PROD = 'production', 5 | SELF_HOSTED = 'self-hosted', 6 | } 7 | 8 | export const NODE_ENV: NodeEnv = import.meta.env.VITE_ENVIRONMENT as NodeEnv; 9 | -------------------------------------------------------------------------------- /docs/voidInvoice.md: -------------------------------------------------------------------------------- 1 | ### Problem statement 2 | Whenever we void an invoice, we need to allow the option to add metadata, key value pairs. 3 | 4 | 5 | ### GOALS: 6 | 1. Analyze the current setup 7 | 2. Make sure you reuse the compoenet already created for metadata 8 | -------------------------------------------------------------------------------- /src/components/organisms/PlanForm/index.ts: -------------------------------------------------------------------------------- 1 | export { default as PlanDetailsSection } from './PlanDetailsSection'; 2 | export { default as SetupChargesSection } from './SetupChargesSection'; 3 | export { default as RecurringChargesForm } from './RecurringChargesForm'; 4 | -------------------------------------------------------------------------------- /src/pages/usage/index.ts: -------------------------------------------------------------------------------- 1 | // Events 2 | export { default as Events } from './events/Events'; 3 | 4 | // Query 5 | export { default as Query } from './query/Query'; 6 | 7 | // Cost Analytics 8 | export { default as CostAnalytics } from './cost-analytics/CostAnalytics'; 9 | -------------------------------------------------------------------------------- /src/components/atoms/ComingSoon/ComingSoon.tsx: -------------------------------------------------------------------------------- 1 | const ComingSoonTag = () => { 2 | return ( 3 |
Coming Soon
4 | ); 5 | }; 6 | 7 | export default ComingSoonTag; 8 | -------------------------------------------------------------------------------- /src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | 3 | function Skeleton({ className, ...props }: React.HTMLAttributes) { 4 | return
; 5 | } 6 | 7 | export { Skeleton }; 8 | -------------------------------------------------------------------------------- /src/components/molecules/Table/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Table'; 2 | export { default } from './Table'; 3 | export { default as TooltipCell } from './TooltipCell'; 4 | export { default as RedirectCell } from './RedirectCell'; 5 | export { default as Toolbar, type FilterState } from './Toolbar'; 6 | -------------------------------------------------------------------------------- /src/models/Event.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel } from './base'; 2 | 3 | export interface Event extends BaseModel { 4 | readonly customer_id: string; 5 | readonly event_name: string; 6 | readonly external_customer_id: string; 7 | readonly properties: Record; 8 | readonly source: string; 9 | } 10 | -------------------------------------------------------------------------------- /src/types/common/Coupon.ts: -------------------------------------------------------------------------------- 1 | export enum COUPON_TYPE { 2 | FIXED = 'fixed', 3 | PERCENTAGE = 'percentage', 4 | } 5 | 6 | export enum COUPON_CADENCE { 7 | ONCE = 'once', 8 | REPEATED = 'repeated', 9 | FOREVER = 'forever', 10 | } 11 | 12 | export interface CouponRules { 13 | [key: string]: any; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/molecules/Dashboard/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DashboardControls } from './DashboardControls'; 2 | export { default as RecentSubscriptionsCard } from './RecentSubscriptionsCard'; 3 | export { default as RevenueTrendCard } from './RevenueTrendCard'; 4 | export { default as InvoiceIssuesCard } from './InvoiceIssuesCard'; 5 | -------------------------------------------------------------------------------- /src/types/dto/Auth.ts: -------------------------------------------------------------------------------- 1 | export interface SignupData { 2 | email: string; 3 | password?: string; 4 | token?: string; 5 | } 6 | 7 | export interface LoginData { 8 | email: string; 9 | password: string; 10 | } 11 | 12 | export interface LocalUser { 13 | token: string; 14 | user_id: string; 15 | tenant_id: string; 16 | } 17 | -------------------------------------------------------------------------------- /src/models/Environment.ts: -------------------------------------------------------------------------------- 1 | export interface Environment { 2 | id: string; 3 | name: string; 4 | type: ENVIRONMENT_TYPE; 5 | created_at: string; 6 | updated_at: string; 7 | } 8 | 9 | export enum ENVIRONMENT_TYPE { 10 | DEVELOPMENT = 'development', 11 | PRODUCTION = 'production', 12 | } 13 | 14 | export default Environment; 15 | -------------------------------------------------------------------------------- /.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import 'tailwindcss/tailwind.css'; 2 | import type { Preview } from '@storybook/react'; 3 | 4 | const preview: Preview = { 5 | parameters: { 6 | controls: { 7 | matchers: { 8 | color: /(background|color)$/i, 9 | date: /Date$/i, 10 | }, 11 | }, 12 | }, 13 | }; 14 | 15 | export default preview; 16 | -------------------------------------------------------------------------------- /src/types/dto/UserApi.ts: -------------------------------------------------------------------------------- 1 | import { User } from '@/models'; 2 | 3 | export interface GetServiceAccountsResponse { 4 | items: User[]; 5 | pagination?: { 6 | total: number; 7 | limit: number; 8 | offset: number; 9 | }; 10 | } 11 | 12 | export interface CreateServiceAccountPayload { 13 | type: 'service_account'; 14 | roles: string[]; 15 | } 16 | -------------------------------------------------------------------------------- /src/models/Integration.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel } from './base'; 2 | 3 | export interface Integration extends BaseModel { 4 | readonly display_id: string; 5 | readonly expires_at: string; 6 | readonly last_used_at: string; 7 | readonly name: string; 8 | readonly permissions: string[]; 9 | readonly provider: string; 10 | readonly type: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/types/dto/base.ts: -------------------------------------------------------------------------------- 1 | import { ENTITY_STATUS } from '@/models'; 2 | 3 | export interface QueryFilter { 4 | limit?: number; 5 | offset?: number; 6 | status?: ENTITY_STATUS; 7 | sort?: string | any; 8 | order?: string; 9 | expand?: string; 10 | } 11 | 12 | export interface TimeRangeFilter { 13 | start_time?: string; 14 | end_time?: string; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/organisms/index.ts: -------------------------------------------------------------------------------- 1 | export { default as EmptyPage } from './EmptyPage'; 2 | export { default as EntityChargesPage, ENTITY_TYPE } from './EntityChargesPage'; 3 | export { default as PlanPriceTable } from './PlanPriceTable'; 4 | export { AddonTable, PriceTable, SubscriptionActionButton, SubscriptionForm, SubscriptionTable, UsageTable } from './Subscription'; 5 | -------------------------------------------------------------------------------- /src/models/CostSheet.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | import { Price } from './Price'; 3 | 4 | export interface CostSheet extends BaseModel { 5 | readonly name: string; 6 | readonly description: string; 7 | readonly lookup_key: string; 8 | readonly metadata: Metadata; 9 | readonly prices?: Price[]; 10 | } 11 | 12 | export default CostSheet; 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | container_name: flexprice-front 4 | build: 5 | context: . 6 | dockerfile: Dockerfile 7 | ports: 8 | - "3000:3000" 9 | healthcheck: 10 | test: ["CMD", "curl", "-f", "http://localhost:3000"] 11 | interval: 30s 12 | timeout: 10s 13 | retries: 3 14 | start_period: 40s 15 | -------------------------------------------------------------------------------- /src/api/WebhookApi.ts: -------------------------------------------------------------------------------- 1 | import { AxiosClient } from '@/core/axios/verbs'; 2 | import { WebhookDashboardResponse } from '@/types/dto/webhook'; 3 | 4 | class WebhookApi { 5 | static async getWebhookDashboardUrl() { 6 | const baseUrl = '/webhooks'; 7 | return AxiosClient.get(`${baseUrl}/dashboard`); 8 | } 9 | } 10 | 11 | export default WebhookApi; 12 | -------------------------------------------------------------------------------- /src/components/molecules/CreditGrant/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SubscriptionCreditGrantTable } from './SubscriptionCreditGrantTable'; 2 | export { default as CreditGrantsTable } from './CreditGrantsTable'; 3 | export { default as CreditGrantModal } from './CreditGrantModal'; 4 | export { default as UpcomingCreditGrantApplicationsTable } from './UpcomingCreditGrantApplicationsTable'; 5 | -------------------------------------------------------------------------------- /src/types/font.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.otf' { 2 | const src: string; 3 | export default src; 4 | } 5 | 6 | declare module '*.ttf' { 7 | const src: string; 8 | export default src; 9 | } 10 | 11 | declare module '*.woff' { 12 | const src: string; 13 | export default src; 14 | } 15 | 16 | declare module '*.woff2' { 17 | const src: string; 18 | export default src; 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "incremental": true, 5 | "skipLibCheck": true, 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "baseUrl": ".", 11 | "paths": { 12 | "@/*": ["./src/*"] 13 | } 14 | }, 15 | "include": ["vite.config.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /src/components/molecules/Customer/index.ts: -------------------------------------------------------------------------------- 1 | export { default as CreateCustomerDrawer } from './CreateCustomerDrawer'; 2 | export { default as CustomerCard } from './CustomerCard'; 3 | export { default as CustomerTable } from './CustomerTable'; 4 | export { default as CustomerSearchSelect } from './CustomerSearchSelect'; 5 | export type { CustomerSearchSelectProps } from './CustomerSearchSelect'; 6 | -------------------------------------------------------------------------------- /src/components/molecules/InvoiceTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './InvoiceTable'; 2 | export { default as CustomerInvoiceTable } from './CustomerInvoiceTable'; 3 | export { default as InvoiceTableMenu } from './InvoiceTableMenu'; 4 | export { default as InvoiceStatusModal } from './InvoiceStatusModal'; 5 | export { default as InvoicePaymentStatusModal } from './InvoicePaymentStatusModal'; 6 | -------------------------------------------------------------------------------- /src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'; 2 | 3 | const Collapsible = CollapsiblePrimitive.Root; 4 | 5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger; 6 | 7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent; 8 | 9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }; 10 | -------------------------------------------------------------------------------- /src/types/dto/Testimonial.ts: -------------------------------------------------------------------------------- 1 | export interface Testimonial { 2 | companyTitleLogoUrl?: string; 3 | dpUrl: string; 4 | logoUrl: string; 5 | testimonial: string; 6 | name: string; 7 | designation: string; 8 | companyName: string; 9 | label?: string; // e.g., "Series A", "Series B", "YC 23", "YC 25" 10 | labelImageUrl?: string; // Image URL for label (e.g., Y Combinator logo) 11 | } 12 | -------------------------------------------------------------------------------- /src/tests/setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | import { expect, afterEach } from 'vitest'; 3 | import { cleanup } from '@testing-library/react'; 4 | import matchers from '@testing-library/jest-dom/matchers'; 5 | 6 | // Extend Vitest's expect with Testing Library's matchers 7 | expect.extend(matchers); 8 | 9 | // Cleanup after each test 10 | afterEach(() => { 11 | cleanup(); 12 | }); 13 | -------------------------------------------------------------------------------- /src/components/atoms/Select/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Select } from './Select'; 2 | export { default as SearchableSelect } from './SearchableSelect'; 3 | export { default as AsyncSearchableSelect } from './AsyncSearchableSelect'; 4 | export type { SelectOption } from './Select'; 5 | export type { AsyncSearchableSelectProps, SearchConfig, ExtractorsConfig, DisplayConfig, OptionsConfig } from './AsyncSearchableSelect'; 6 | -------------------------------------------------------------------------------- /src/models/Addon.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | 3 | export enum ADDON_TYPE { 4 | ONETIME = 'onetime', 5 | MULTIPLE = 'multiple', 6 | } 7 | 8 | interface Addon extends BaseModel { 9 | readonly name: string; 10 | readonly description: string; 11 | readonly lookup_key: string; 12 | readonly type: ADDON_TYPE; 13 | readonly metadata: Metadata; 14 | } 15 | 16 | export default Addon; 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | flexprice.io 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/types/formatters/BaseEntity.ts: -------------------------------------------------------------------------------- 1 | import { ENTITY_STATUS } from '@/models'; 2 | 3 | export const formatBaseEntityStatusToDisplay = (status: ENTITY_STATUS) => { 4 | switch (status) { 5 | case ENTITY_STATUS.PUBLISHED: 6 | return 'Published'; 7 | case ENTITY_STATUS.DELETED: 8 | return 'Deleted'; 9 | case ENTITY_STATUS.ARCHIVED: 10 | return 'Archived'; 11 | default: 12 | return status; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/types/dto/Environment.ts: -------------------------------------------------------------------------------- 1 | import { ENVIRONMENT_TYPE, Pagination, Environment } from '@/models'; 2 | 3 | export interface UpdateEnvironmentPayload { 4 | name?: string; 5 | type?: ENVIRONMENT_TYPE; 6 | } 7 | 8 | export interface CreateEnvironmentPayload { 9 | name: string; 10 | type: ENVIRONMENT_TYPE; 11 | } 12 | export interface ListEnvironmentResponse extends Pagination { 13 | environments: Environment[]; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/generate-meta.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import { execSync } from 'child_process'; 4 | 5 | const versionId = execSync('git rev-parse HEAD').toString().trim(); 6 | 7 | const meta = { versionId }; 8 | 9 | const outPath = path.resolve(process.cwd(), 'public', 'meta.json'); 10 | fs.writeFileSync(outPath, JSON.stringify(meta)); 11 | console.log('Generated meta.json with versionId:', versionId); 12 | -------------------------------------------------------------------------------- /src/utils/common/format_chips.ts: -------------------------------------------------------------------------------- 1 | import { ENTITY_STATUS } from '@/models'; 2 | 3 | const formatChips = (data: string): string => { 4 | switch (data) { 5 | case ENTITY_STATUS.PUBLISHED: 6 | return 'Active'; 7 | case ENTITY_STATUS.ARCHIVED: 8 | return 'Inactive'; 9 | case ENTITY_STATUS.DELETED: 10 | return 'Inactive'; 11 | default: 12 | return 'Inactive'; 13 | } 14 | }; 15 | 16 | export default formatChips; 17 | -------------------------------------------------------------------------------- /src/core/axios/types.ts: -------------------------------------------------------------------------------- 1 | export interface ServerError { 2 | success: false; 3 | error: { message: string; internal_error: string; details: Record }; 4 | } 5 | 6 | // adds the same shape to the global namespace for legacy code, tests, etc. 7 | declare global { 8 | interface ServerError { 9 | success: false; 10 | error: { message: string; internal_error: string; details: Record }; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/types/dto/Integration.ts: -------------------------------------------------------------------------------- 1 | import { Integration, Pagination } from '@/models'; 2 | 3 | export interface CreateIntegrationRequest { 4 | provider: string; 5 | credentials: { 6 | key: string; 7 | }; 8 | name: string; 9 | } 10 | 11 | export interface LinkedinIntegrationResponse { 12 | providers: string[]; 13 | } 14 | 15 | export interface IntegrationResponse { 16 | items: Integration[]; 17 | pagination: Pagination; 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/common/format_cadence_chip.ts: -------------------------------------------------------------------------------- 1 | import { CadenceStatus } from '@/types/common'; 2 | 3 | const formatCadenceChip = (data: string): string => { 4 | switch (data) { 5 | case CadenceStatus.ONCE: 6 | return 'Once'; 7 | case CadenceStatus.REPEAT: 8 | return 'Repeat'; 9 | case CadenceStatus.FOREVER: 10 | return 'Forever'; 11 | default: 12 | return 'Once'; 13 | } 14 | }; 15 | 16 | export default formatCadenceChip; 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1: Build the React app 2 | FROM node:20-alpine AS build 3 | 4 | # Set working directory 5 | WORKDIR /app 6 | 7 | # Copy package files for dependency installation 8 | COPY package.json package-lock.json ./ 9 | 10 | # Install dependencies with locked versions 11 | RUN npm ci 12 | 13 | # Copy all files to the container 14 | COPY . . 15 | 16 | # Build the Vite app 17 | RUN npm run build 18 | 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /src/pages/customer/creditnotes/CreditNoteDetailsPage.tsx: -------------------------------------------------------------------------------- 1 | import { useParams } from 'react-router'; 2 | import CreditNoteDetails from './CreditNoteDetails'; 3 | 4 | const CreditNoteDetailsPage = () => { 5 | const { credit_note_id: creditNoteId } = useParams(); 6 | 7 | return ( 8 | <> 9 | 10 | 11 | ); 12 | }; 13 | 14 | export default CreditNoteDetailsPage; 15 | -------------------------------------------------------------------------------- /src/pages/product-catalog/addons/AddonCharges.tsx: -------------------------------------------------------------------------------- 1 | import { useParams } from 'react-router'; 2 | import EntityChargesPage, { ENTITY_TYPE } from '@/components/organisms/EntityChargesPage'; 3 | 4 | const AddonChargesPage = () => { 5 | const { addonId } = useParams<{ addonId: string }>(); 6 | 7 | return ; 8 | }; 9 | 10 | export default AddonChargesPage; 11 | -------------------------------------------------------------------------------- /src/components/atoms/Spacer/Spacer.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react'; 2 | 3 | interface Props { 4 | width?: string | number; 5 | height?: string | number; 6 | className?: string; 7 | } 8 | const Spacer: FC = ({ height, width, className }) => { 9 | return ( 10 |
16 | ); 17 | }; 18 | 19 | export default Spacer; 20 | -------------------------------------------------------------------------------- /src/models/base.ts: -------------------------------------------------------------------------------- 1 | export interface BaseModel { 2 | id: string; 3 | created_at: string; 4 | updated_at: string; 5 | created_by: string; 6 | updated_by: string; 7 | tenant_id: string; 8 | status: ENTITY_STATUS; 9 | environment_id: string; 10 | } 11 | 12 | export enum ENTITY_STATUS { 13 | PUBLISHED = 'published', 14 | DELETED = 'deleted', 15 | ARCHIVED = 'archived', 16 | } 17 | 18 | export interface Metadata { 19 | [key: string]: string; 20 | } 21 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | .vercel 26 | tsconfig.tsbuildinfo 27 | tsconfig.app.tsbuildinfo 28 | # Sentry Config File 29 | -------------------------------------------------------------------------------- /src/pages/product-catalog/cost-sheets/CostSheetCharges.tsx: -------------------------------------------------------------------------------- 1 | import { useParams } from 'react-router'; 2 | import { EntityChargesPage, ENTITY_TYPE } from '@/components/organisms'; 3 | 4 | const CostSheetChargesPage = () => { 5 | const { costSheetId } = useParams<{ costSheetId: string }>(); 6 | 7 | return ; 8 | }; 9 | 10 | export default CostSheetChargesPage; 11 | -------------------------------------------------------------------------------- /src/types/dto/LineItemCommitmentConfig.ts: -------------------------------------------------------------------------------- 1 | export enum CommitmentType { 2 | AMOUNT = 'amount', 3 | QUANTITY = 'quantity', 4 | } 5 | 6 | export interface LineItemCommitmentConfig { 7 | commitment_type: CommitmentType; 8 | commitment_amount?: number; 9 | commitment_quantity?: number; 10 | overage_factor: number; 11 | enable_true_up: boolean; 12 | is_window_commitment: boolean; 13 | } 14 | 15 | export type LineItemCommitmentsMap = Record; 16 | -------------------------------------------------------------------------------- /src/models/Group.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | 3 | export enum GROUP_ENTITY_TYPE { 4 | PRICE = 'price', 5 | PLAN = 'plan', 6 | ADDON = 'addon', 7 | FEATURE = 'feature', 8 | METER = 'meter', 9 | CUSTOMER = 'customer', 10 | } 11 | 12 | export interface Group extends BaseModel { 13 | readonly name: string; 14 | readonly lookup_key: string; 15 | readonly entity_type: GROUP_ENTITY_TYPE; 16 | readonly entity_ids: string[]; 17 | readonly metadata: Metadata | null; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/atoms/NoDataCard/NoDataCard.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import Card, { CardHeader } from '../Card'; 3 | 4 | interface NoDataCardProps { 5 | title: string; 6 | subtitle: string; 7 | cta?: React.ReactNode; 8 | } 9 | 10 | const NoDataCard: FC = ({ title, subtitle, cta }) => { 11 | return ( 12 | 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default NoDataCard; 19 | -------------------------------------------------------------------------------- /src/hooks/usePagePosition.tsx: -------------------------------------------------------------------------------- 1 | import { useLayoutEffect, useState } from 'react'; 2 | 3 | export default function useWindowPosition() { 4 | const [scrollPosition, setPosition] = useState(0); 5 | useLayoutEffect(() => { 6 | function updatePosition() { 7 | setPosition(window.pageYOffset); 8 | } 9 | window.addEventListener('scroll', updatePosition); 10 | updatePosition(); 11 | return () => window.removeEventListener('scroll', updatePosition); 12 | }, []); 13 | return scrollPosition; 14 | } 15 | -------------------------------------------------------------------------------- /src/types/dto/User.ts: -------------------------------------------------------------------------------- 1 | export interface CreateUserRequest { 2 | name: string; 3 | email: string; 4 | password: string; 5 | } 6 | 7 | export interface UpdateTenantPayload { 8 | billing_details: { 9 | address: { 10 | address_line1: string; 11 | address_line2: string; 12 | address_city: string; 13 | address_state: string; 14 | address_postal_code: string; 15 | address_country: string; 16 | }; 17 | email?: string; 18 | help_email?: string; 19 | phone?: string; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from "@storybook/react-vite"; 2 | 3 | const config: StorybookConfig = { 4 | stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], 5 | addons: [ 6 | "@storybook/addon-onboarding", 7 | "@storybook/addon-essentials", 8 | "@chromatic-com/storybook", 9 | "@storybook/addon-interactions", 10 | ], 11 | framework: { 12 | name: "@storybook/react-vite", 13 | options: {}, 14 | }, 15 | }; 16 | export default config; 17 | -------------------------------------------------------------------------------- /src/models/Plan.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | import { Entitlement } from './Entitlement'; 3 | import { Price } from './Price'; 4 | import { CreditGrant } from './CreditGrant'; 5 | 6 | export interface Plan extends BaseModel { 7 | readonly description: string; 8 | readonly lookup_key: string; 9 | readonly name: string; 10 | readonly entitlements: Entitlement[]; 11 | readonly prices: Price[]; 12 | readonly credit_grants: CreditGrant[]; 13 | readonly metadata?: Metadata; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/molecules/Sidebar/UserProfile.tsx: -------------------------------------------------------------------------------- 1 | const UserProfile = () => { 2 | return ( 3 |
4 | company logo 9 |

Simplismart

10 |
11 | ); 12 | }; 13 | export default UserProfile; 14 | -------------------------------------------------------------------------------- /src/models/Customer.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | 3 | export interface Customer extends BaseModel { 4 | address_city: string; 5 | address_country: string; 6 | address_line1: string; 7 | address_line2: string; 8 | address_postal_code: string; 9 | address_state: string; 10 | email: string; 11 | external_id: string; 12 | metadata: Metadata; 13 | name: string; 14 | environment_id: string; 15 | parent_customer_id?: string; 16 | parent_customer?: Customer; 17 | } 18 | 19 | export default Customer; 20 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | 5 | server_name _; 6 | 7 | root /usr/share/nginx/html; 8 | index index.html; 9 | 10 | location / { 11 | try_files $uri /index.html; 12 | } 13 | 14 | # Enable Gzip Compression 15 | gzip on; 16 | gzip_types text/css text/javascript application/javascript application/json application/xml text/plain text/xml; 17 | gzip_vary on; 18 | 19 | # Security Headers 20 | add_header Content-Security-Policy "frame-ancestors 'self';" always; 21 | } 22 | -------------------------------------------------------------------------------- /src/components/molecules/QueryBuilder/index.ts: -------------------------------------------------------------------------------- 1 | export { default as QueryBuilder } from './QueryBuilder'; 2 | export { default as FilterPopover } from './FilterPopover'; 3 | export { default as SortDropdown } from './SortDropdown'; 4 | export { default as FilterMultiSelect } from './FilterMultiSelect'; 5 | export type { FilterCondition, FilterField, FilterFieldType, FilterOperator, DataType, SortDirection } from '@/types/common/QueryBuilder'; 6 | export { sanitizeFilterConditions, sanitizeSortConditions } from '@/types/formatters/QueryBuilder'; 7 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/index.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /src/types/common/index.ts: -------------------------------------------------------------------------------- 1 | export { CadenceStatus } from './BaseCadence'; 2 | export { COUPON_TYPE, COUPON_CADENCE } from './Coupon'; 3 | export type { CouponRules } from './Coupon'; 4 | export { FilterFieldType, DEFAULT_OPERATORS_PER_DATA_TYPE, DataType, FilterOperator, SortDirection } from './QueryBuilder'; 5 | export type { FilterField, FilterCondition } from './QueryBuilder'; 6 | 7 | // Environment types 8 | export { NodeEnv, NODE_ENV } from './Environment'; 9 | 10 | // Common interface types 11 | export type { Filters } from './Filters'; 12 | -------------------------------------------------------------------------------- /src/models/CustomerEntitlement.ts: -------------------------------------------------------------------------------- 1 | import Feature from './Feature'; 2 | 3 | export interface CustomerEntitlement { 4 | entitlement: { 5 | is_enabled: boolean; 6 | is_soft_limit: boolean; 7 | static_values: string[]; 8 | usage_limit: number; 9 | usage_reset_period: string; 10 | }; 11 | feature: Feature; 12 | sources: { 13 | entitlement_id: string; 14 | is_enabled: boolean; 15 | plan_id: string; 16 | plan_name: string; 17 | subscription_id: string; 18 | quantity: number; 19 | static_value: string; 20 | usage_limit: number; 21 | }[]; 22 | } 23 | -------------------------------------------------------------------------------- /src/models/User.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id: string; 3 | tenant: { 4 | id: string; 5 | name: string; 6 | billing_details: { 7 | address: { 8 | address_line1: string; 9 | address_line2: string; 10 | address_city: string; 11 | address_state: string; 12 | address_postal_code: string; 13 | address_country: string; 14 | }; 15 | }; 16 | status: string; 17 | created_at: string; 18 | updated_at: string; 19 | }; 20 | email: string; 21 | name?: string; 22 | type?: 'user' | 'service_account'; 23 | roles?: string[]; 24 | } 25 | -------------------------------------------------------------------------------- /src/models/Coupon.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | import { COUPON_TYPE, COUPON_CADENCE, CouponRules } from '@/types/common/Coupon'; 3 | 4 | export interface Coupon extends BaseModel { 5 | name: string; 6 | redeem_after?: string; 7 | redeem_before?: string; 8 | max_redemptions?: number; 9 | total_redemptions: number; 10 | rules?: CouponRules; 11 | amount_off?: string; 12 | percentage_off?: string; 13 | type: COUPON_TYPE; 14 | cadence: COUPON_CADENCE; 15 | duration_in_periods?: number; 16 | currency: string; 17 | metadata?: Metadata; 18 | } 19 | -------------------------------------------------------------------------------- /src/types/enums/ChargebeeWebhookEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum for Chargebee webhook events used in the application 3 | * This provides type safety and prevents typos when working with webhook events 4 | */ 5 | export enum ChargebeeWebhookEvents { 6 | // Payment events 7 | PAYMENT_SUCCEEDED = 'payment_succeeded', 8 | } 9 | 10 | /** 11 | * Helper function to get default webhook events 12 | * @returns Array of default Chargebee webhook events 13 | */ 14 | export const getDefaultChargebeeWebhookEvents = (): ChargebeeWebhookEvents[] => [ChargebeeWebhookEvents.PAYMENT_SUCCEEDED]; 15 | -------------------------------------------------------------------------------- /src/types/enums/QuickBooksWebhookEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum for QuickBooks webhook events used in the application 3 | * This provides type safety and prevents typos when working with webhook events 4 | */ 5 | export enum QuickBooksWebhookEvents { 6 | // Payment events 7 | PAYMENT_CREATE = 'Payment.Create', 8 | } 9 | 10 | /** 11 | * Helper function to get default webhook events 12 | * @returns Array of default QuickBooks webhook events 13 | */ 14 | export const getDefaultQuickBooksWebhookEvents = (): QuickBooksWebhookEvents[] => [QuickBooksWebhookEvents.PAYMENT_CREATE]; 15 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | We value security for the project very highly. We encourage all users to report any vulnerabilities they discover to us. 6 | If you find a security vulnerability in the Flexprice project, please report it responsibly by sending an email to ola@flexprice.io 7 | 8 | At this juncture, we don't have a bug bounty program. We are a small team trying to solve a big problem. We urge you to report any vulnerabilities responsibly 9 | so that we can continue building a secure application for the entire community. 10 | -------------------------------------------------------------------------------- /src/pages/auth/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Auth } from './Auth'; 2 | export { default as EmailVerification } from './EmailVerification'; 3 | export { default as ForgotPasswordForm } from './ForgotPasswordForm'; 4 | export { default as GoogleSignin } from './GoogleSignin'; 5 | export { default as LandingSection } from './LandingSection'; 6 | export { default as LoginForm } from './LoginForm'; 7 | export { default as ResendVerification } from './ResendVerification'; 8 | export { default as SignupConfirmation } from './SignupConfirmation'; 9 | export { default as SignupForm } from './SignupForm'; 10 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'always', 3 | bracketSpacing: true, 4 | bracketSameLine: true, 5 | embeddedLanguageFormatting: 'auto', 6 | htmlWhitespaceSensitivity: 'css', 7 | insertPragma: false, 8 | jsxBracketSameLine: false, 9 | jsxSingleQuote: true, 10 | printWidth: 140, 11 | proseWrap: 'preserve', 12 | quoteProps: 'as-needed', 13 | requirePragma: false, 14 | semi: true, 15 | singleQuote: true, 16 | tabWidth: 2, 17 | trailingComma: 'all', 18 | useTabs: true, 19 | vueIndentScriptAndStyle: false, 20 | jsxBracketSameLine: true, 21 | endOfLine: 'auto', 22 | }; 23 | -------------------------------------------------------------------------------- /src/models/expand.ts: -------------------------------------------------------------------------------- 1 | export enum EXPAND { 2 | PRICES = 'prices', 3 | PLAN = 'plan', 4 | METERS = 'meters', 5 | FEATURES = 'features', 6 | PLANS = 'plans', 7 | ENTITLEMENTS = 'entitlements', 8 | SCHEDULE = 'schedule', 9 | INVOICE = 'invoice', 10 | SUBSCRIPTION = 'subscription', 11 | CUSTOMER = 'customer', 12 | CREDIT_NOTE = 'credit_note', 13 | CREDIT_GRANT = 'credit_grant', 14 | TAX_APPLIED = 'tax_applied', 15 | TAX_RATE = 'tax_rate', 16 | TAX_ASSOCIATION = 'tax_association', 17 | ADDONS = 'addons', 18 | PARENT_CUSTOMER = 'parent_customer', 19 | CREATED_BY_USER = 'created_by_user', 20 | } 21 | -------------------------------------------------------------------------------- /src/types/dto/Tenant.ts: -------------------------------------------------------------------------------- 1 | import { Subscription, CustomerUsage, Pagination, TenantBillingDetails, Metadata } from '@/models'; 2 | 3 | export interface GetBillingdetailsResponse { 4 | subscriptions: Subscription[]; 5 | usage: { 6 | customer_id: string; 7 | features: CustomerUsage[]; 8 | pagination: Pagination; 9 | period: { 10 | end_time: string; 11 | period: string; 12 | start_time: string; 13 | }; 14 | }; 15 | } 16 | 17 | export interface UpdateTenantRequest { 18 | readonly name?: string; 19 | readonly billing_details?: TenantBillingDetails; 20 | readonly metadata?: Metadata; 21 | } 22 | -------------------------------------------------------------------------------- /src/constants/index.ts: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // CONSTANTS EXPORTS 3 | // ============================================================================= 4 | 5 | // Payment Constants 6 | export * from './payment'; 7 | 8 | // Common Utilities 9 | export * from './common'; 10 | 11 | // Constants 12 | export * from './constants'; 13 | 14 | // Re-export model enums for convenience 15 | export { CREDIT_NOTE_TYPE, CREDIT_NOTE_STATUS, CREDIT_NOTE_REASON } from '@/models'; 16 | export { INVOICE_TYPE as InvoiceType, INVOICE_CADENCE, BILLING_CADENCE } from '@/models'; 17 | -------------------------------------------------------------------------------- /src/components/atoms/Button/AddButton.tsx: -------------------------------------------------------------------------------- 1 | import { Plus } from 'lucide-react'; 2 | import Button, { ButtonProps } from './Button'; 3 | import { cn } from '@/lib/utils'; 4 | 5 | interface AddButtonProps extends Omit { 6 | /** 7 | * Custom label text. Defaults to "Add" 8 | */ 9 | label?: string; 10 | } 11 | 12 | const AddButton = ({ label = 'Add', className, children, ...props }: AddButtonProps) => { 13 | return ( 14 | 17 | ); 18 | }; 19 | 20 | export default AddButton; 21 | -------------------------------------------------------------------------------- /src/types/dto/SecretApi.ts: -------------------------------------------------------------------------------- 1 | import { Pagination, SecretKey } from '@/models'; 2 | 3 | export interface GetAllSecretKeysResponse { 4 | items: SecretKey[]; 5 | pagination: Pagination; 6 | } 7 | 8 | export interface CreateSecretKeyPayload { 9 | name: string; 10 | expires_at?: string; 11 | type: string; 12 | service_account_id?: string; // For service account API keys 13 | roles?: string[]; // Optional: for user account API keys with specific roles 14 | user_id?: string; // Optional: for service account API keys 15 | } 16 | 17 | export interface CreateSecretKeyResponse { 18 | api_key: string; 19 | secret: SecretKey; 20 | } 21 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import react from '@vitejs/plugin-react'; 3 | import fs from 'fs'; 4 | import { defineConfig } from 'vite'; 5 | 6 | const meta = JSON.parse(fs.readFileSync('./public/meta.json', 'utf8')); 7 | 8 | export default defineConfig({ 9 | plugins: [react()], 10 | define: { 11 | __APP_VERSION__: JSON.stringify(meta.versionId), 12 | }, 13 | resolve: { 14 | alias: { 15 | '@': path.resolve(__dirname, './src'), 16 | }, 17 | }, 18 | server: { 19 | cors: { 20 | origin: 'http://localhost:3000', 21 | methods: ['GET', 'POST'], 22 | }, 23 | host: 'localhost', 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | yarn.lock 26 | package-lock.json 27 | .env 28 | .vercel 29 | tsconfig.tsbuildinfo 30 | tsconfig.app.tsbuildinfo 31 | # Sentry Config File 32 | .env.sentry-build-plugin 33 | .dev 34 | # dotenv-store encryption key 35 | .env.store.key 36 | 37 | # build 38 | vite.config.js -------------------------------------------------------------------------------- /src/models/SecretKey.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel } from './base'; 2 | 3 | export interface SecretKey extends BaseModel { 4 | readonly display_id: string; 5 | readonly expires_at?: string; 6 | readonly last_used_at: string; 7 | readonly name: string; 8 | readonly permissions: string[]; 9 | readonly provider: string; 10 | readonly type: SECRET_KEY_TYPE; 11 | readonly user_id?: string; 12 | readonly roles?: string[]; 13 | readonly user_type?: 'user' | 'service_account'; 14 | } 15 | 16 | export enum SECRET_KEY_TYPE { 17 | PRIVATE_KEY = 'private_key', 18 | PUBLISHABLE_KEY = 'publishable_key', 19 | INTEGRATION = 'integration', 20 | } 21 | -------------------------------------------------------------------------------- /src/api/RbacApi.ts: -------------------------------------------------------------------------------- 1 | import { AxiosClient } from '@/core/axios/verbs'; 2 | 3 | export interface RbacRole { 4 | id: string; 5 | name: string; 6 | description: string; 7 | permissions: { 8 | [entity: string]: string[]; 9 | }; 10 | } 11 | 12 | export interface GetRolesResponse { 13 | roles: RbacRole[]; 14 | } 15 | 16 | class RbacApi { 17 | private static baseUrl = '/rbac'; 18 | 19 | // Fetch all available roles 20 | public static async getAllRoles(): Promise { 21 | const response = await AxiosClient.get(`${this.baseUrl}/roles`); 22 | return response.roles; 23 | } 24 | } 25 | 26 | export default RbacApi; 27 | -------------------------------------------------------------------------------- /src/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | const MOBILE_BREAKPOINT = 768; 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined); 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 12 | }; 13 | mql.addEventListener('change', onChange); 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 15 | return () => mql.removeEventListener('change', onChange); 16 | }, []); 17 | 18 | return !!isMobile; 19 | } 20 | -------------------------------------------------------------------------------- /src/types/enums/RazorpayWebhookEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum for Razorpay webhook events used in the application 3 | * This provides type safety and prevents typos when working with webhook events 4 | */ 5 | export enum RazorpayWebhookEvents { 6 | // Payment events 7 | PAYMENT_CAPTURED = 'payment.captured', 8 | PAYMENT_FAILED = 'payment.failed', 9 | } 10 | 11 | /** 12 | * Helper function to get default webhook events 13 | * @returns Array of default Razorpay webhook events 14 | */ 15 | export const getDefaultRazorpayWebhookEvents = (): RazorpayWebhookEvents[] => [ 16 | RazorpayWebhookEvents.PAYMENT_CAPTURED, 17 | RazorpayWebhookEvents.PAYMENT_FAILED, 18 | ]; 19 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import react from '@vitejs/plugin-react'; 3 | import path from 'path'; 4 | 5 | export default defineConfig({ 6 | test: { 7 | globals: true, 8 | environment: 'jsdom', 9 | include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], 10 | setupFiles: ['./src/tests/setup.ts'], 11 | coverage: { 12 | provider: 'v8', 13 | reporter: ['text', 'json', 'html'], 14 | exclude: [ 15 | 'node_modules/', 16 | 'src/tests/setup.ts', 17 | ], 18 | }, 19 | }, 20 | plugins: [react()], 21 | resolve: { 22 | alias: { 23 | '@': path.resolve(__dirname, './src'), 24 | }, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /src/pages/index.ts: -------------------------------------------------------------------------------- 1 | // Auth pages 2 | export * from './auth'; 3 | 4 | // Customer pages 5 | export * from './customer'; 6 | 7 | // Developer pages 8 | export * from './developer'; 9 | 10 | // Error pages 11 | export * from './error'; 12 | 13 | // Insights tools pages 14 | export * from './insights-tools'; 15 | 16 | // Onboarding pages 17 | export * from './onboarding'; 18 | 19 | // Product catalog pages 20 | export * from './product-catalog'; 21 | 22 | // Settings pages 23 | export * from './settings'; 24 | 25 | // Usage pages 26 | export * from './usage'; 27 | 28 | // Webhooks pages 29 | export * from './webhooks'; 30 | 31 | // Home pages 32 | export * from './home'; 33 | -------------------------------------------------------------------------------- /src/components/atoms/Label/Label.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import React from 'react'; 3 | 4 | interface LabelProps extends React.LabelHTMLAttributes { 5 | label: string; 6 | disabled?: boolean; 7 | labelClassName?: string; 8 | children?: React.ReactNode; 9 | } 10 | 11 | const Label = ({ label, disabled, labelClassName, children, htmlFor, ...props }: LabelProps) => { 12 | return ( 13 | 19 | ); 20 | }; 21 | 22 | export default Label; 23 | -------------------------------------------------------------------------------- /src/components/organisms/Subscription/index.ts: -------------------------------------------------------------------------------- 1 | export { default as PriceTable } from './PriceTable'; 2 | export { default as SubscriptionForm } from './SubscriptionForm'; 3 | export { default as SubscriptionTable } from './SubscriptionTable'; 4 | export { default as SubscriptionActionButton } from './SubscriptionActionButton'; 5 | export { default as UsageTable } from './UsageTable'; 6 | export { default as AddonTable } from './PriceTable'; 7 | export { default as SubscriptionWithOverrides } from './SubscriptionWithOverrides'; 8 | export { default as SubscriptionCreationExample } from './SubscriptionCreationExample'; 9 | export { default as PriceOverrideSummary } from './PriceOverrideSummary'; 10 | -------------------------------------------------------------------------------- /src/store/useApiDocsStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | 3 | export interface ApiDocsSnippet { 4 | label: string; 5 | description: string; 6 | curl: string; 7 | Python?: string; 8 | JavaScript?: string; 9 | PHP?: string; 10 | Java?: string; 11 | Go?: string; 12 | 'C#'?: string; 13 | Ruby?: string; 14 | Swift?: string; 15 | } 16 | 17 | interface ApiDocsState { 18 | snippets: ApiDocsSnippet[]; 19 | setDocs: (snippets: ApiDocsSnippet[]) => void; 20 | clearDocs: () => void; 21 | } 22 | 23 | export const useApiDocsStore = create((set) => ({ 24 | snippets: [], 25 | setDocs: (snippets) => set({ snippets }), 26 | clearDocs: () => set({ snippets: [] }), 27 | })); 28 | -------------------------------------------------------------------------------- /src/utils/common/format_number.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Format a number with thousands separators and optional decimal places 3 | * @param value The number to format 4 | * @param decimals Number of decimal places (default: 0) 5 | * @returns Formatted number string 6 | */ 7 | const formatNumber = (value: number, decimals: number = 0): string => { 8 | if (!value) return '-'; 9 | 10 | // Clamp decimals to valid range (0-20) 11 | const clampedDecimals = Math.max(0, Math.min(20, decimals)); 12 | 13 | return new Intl.NumberFormat('en-US', { 14 | minimumFractionDigits: clampedDecimals, 15 | maximumFractionDigits: clampedDecimals, 16 | }).format(value); 17 | }; 18 | 19 | export default formatNumber; 20 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import react from '@vitejs/plugin-react'; 3 | import fs from 'fs'; 4 | import { defineConfig } from 'vite'; 5 | var meta = JSON.parse(fs.readFileSync('./public/meta.json', 'utf8')); 6 | export default defineConfig({ 7 | plugins: [react()], 8 | define: { 9 | __APP_VERSION__: JSON.stringify(meta.versionId), 10 | }, 11 | resolve: { 12 | alias: { 13 | '@': path.resolve(__dirname, './src'), 14 | }, 15 | }, 16 | server: { 17 | cors: { 18 | origin: 'http://localhost:3000', 19 | methods: ['GET', 'POST'], 20 | }, 21 | host: 'localhost', 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /src/models/ImportTask.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, Metadata } from './base'; 2 | 3 | export interface ImportTask extends BaseModel { 4 | readonly task_type: string; 5 | readonly entity_type: string; 6 | readonly file_url: string; 7 | readonly file_name: string; 8 | readonly file_type: string; 9 | readonly task_status: string; 10 | readonly processed_records: number; 11 | readonly successful_records: number; 12 | readonly failed_records: number; 13 | readonly tenant_id: string; 14 | readonly completed_at: string; 15 | readonly error_summary: string; 16 | readonly failed_at: string; 17 | readonly metadata: Metadata; 18 | readonly started_at: string; 19 | readonly total_records: number; 20 | } 21 | -------------------------------------------------------------------------------- /src/utils/common/api_helper.ts: -------------------------------------------------------------------------------- 1 | import { EXPAND } from '@/models/expand'; 2 | 3 | export const generateExpandQueryParams = (expand: EXPAND[]): string => { 4 | return expand.join(','); 5 | }; 6 | 7 | export const generateQueryParams = (baseUrl: string, params: Record): string => { 8 | const queryParams = Object.keys(params) 9 | .filter((key) => key && params[key] !== undefined && params[key] !== null) 10 | .map((key) => { 11 | const value = Array.isArray(params[key]) ? params[key].join(',') : params[key]; 12 | return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`; 13 | }) 14 | .join('&'); 15 | 16 | return queryParams ? `${baseUrl}?${queryParams}` : baseUrl; 17 | }; 18 | -------------------------------------------------------------------------------- /src/models/Connection.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel } from './base'; 2 | 3 | export interface Connection extends BaseModel { 4 | readonly name: string; 5 | readonly provider_type: string; 6 | readonly environment_id: string; 7 | readonly tenant_id: string; 8 | readonly connection_status: CONNECTION_STATUS; 9 | } 10 | 11 | export enum CONNECTION_PROVIDER_TYPE { 12 | STRIPE = 'stripe', 13 | RAZORPAY = 'razorpay', 14 | CHARGEBEE = 'chargebee', 15 | S3 = 's3', 16 | HUBSPOT = 'hubspot', 17 | QUICKBOOKS = 'quickbooks', 18 | NOMOD = 'nomod', 19 | // Add more providers as needed 20 | } 21 | 22 | export enum CONNECTION_STATUS { 23 | PUBLISHED = 'published', 24 | DRAFT = 'draft', 25 | ARCHIVED = 'archived', 26 | } 27 | -------------------------------------------------------------------------------- /src/hooks/useUser.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { UserApi } from '@/api/UserApi'; 3 | import AuthService from '@/core/auth/AuthService'; 4 | 5 | const useUser = () => { 6 | const tokenStr = AuthService.getAcessToken(); 7 | 8 | const { 9 | data: user, 10 | isLoading: loading, 11 | error, 12 | refetch, 13 | } = useQuery({ 14 | queryKey: ['user', tokenStr], 15 | queryFn: async () => { 16 | return await UserApi.me(); 17 | }, 18 | enabled: !!tokenStr, 19 | retry: 4, 20 | retryDelay: 1000, 21 | // gcTime: 1000 * 60 * 5, 22 | // staleTime: 1000 * 60 * 5, 23 | }); 24 | 25 | return { user, loading, error, refetch }; 26 | }; 27 | 28 | export default useUser; 29 | -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/lib/utils'; 4 | 5 | const Textarea = React.forwardRef>(({ className, ...props }, ref) => { 6 | return ( 7 |