types: Abstract inline interfaces to @plunk/types

This commit is contained in:
Dries Augustyns
2026-01-01 09:09:03 +01:00
parent 519b131792
commit 38da58e5e9
50 changed files with 639 additions and 462 deletions
+1 -1
View File
@@ -107,7 +107,7 @@ export function DomainsSettings({projectId}: DomainsSettingsProps) {
setVerificationStatus(prev => ({
...prev,
[newDomain.id]: {
tokens: newDomain.dkimTokens,
tokens: newDomain.dkimTokens as string[] | null,
status: 'Pending',
verified: false,
},
@@ -298,7 +298,7 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT
subscribeUrl: `${window.location.origin}/subscribe/${contact.id}`,
manageUrl: `${window.location.origin}/manage/${contact.id}`,
data: contact.data || {},
...contact.data,
...(contact.data as Record<string, unknown> | null || {}),
};
return replaceVariables(currentHtml, contactData);
@@ -317,7 +317,7 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT
subscribeUrl: `${window.location.origin}/subscribe/${contact.id}`,
manageUrl: `${window.location.origin}/manage/${contact.id}`,
data: contact.data || {},
...contact.data,
...(contact.data as Record<string, unknown> | null || {}),
};
return replaceVariables(subject, contactData);
+5 -15
View File
@@ -1,19 +1,9 @@
import type {BillingLimitsResponse, CategoryUsage} from '@plunk/types';
import useSWR from 'swr';
export interface CategoryLimit {
usage: number;
limit: number | null;
percentage: number;
isWarning: boolean;
isBlocked: boolean;
}
export interface BillingLimitsData {
workflows: CategoryLimit;
campaigns: CategoryLimit;
transactional: CategoryLimit;
currency: string | null;
}
// Re-export for backward compatibility
export type CategoryLimit = CategoryUsage;
export type BillingLimitsData = BillingLimitsResponse;
/**
* Hook to fetch billing limits for a project
@@ -22,7 +12,7 @@ export interface BillingLimitsData {
* Paid tier projects (with subscription): Shows per-category usage with custom limits
*/
export function useBillingLimits(projectId: string | undefined, billingEnabled: boolean) {
const {data, error, mutate, isLoading} = useSWR<BillingLimitsData>(
const {data, error, mutate, isLoading} = useSWR<BillingLimitsResponse>(
projectId && billingEnabled ? `/users/@me/projects/${projectId}/billing-limits` : null,
{
revalidateOnFocus: false,
+4 -13
View File
@@ -1,16 +1,7 @@
import type {Contact} from '@plunk/db';
import type {CursorPaginatedResponse} from '@plunk/types';
import useSWR from 'swr';
export interface Contact {
id: string;
email: string;
data?: Record<string, unknown>;
}
export interface ContactsResponse {
contacts: Contact[];
total: number;
}
interface UseContactsOptions {
limit?: number;
search?: string;
@@ -28,7 +19,7 @@ export function useContacts(options: UseContactsOptions = {}) {
params.set('search', search);
}
const {data, error, mutate, isLoading} = useSWR<ContactsResponse>(
const {data, error, mutate, isLoading} = useSWR<CursorPaginatedResponse<Contact>>(
`/contacts?${params.toString()}`,
{
revalidateOnFocus: false,
@@ -37,7 +28,7 @@ export function useContacts(options: UseContactsOptions = {}) {
);
return {
contacts: data?.contacts || [],
contacts: data?.data || [],
total: data?.total || 0,
error,
isLoading,
+5 -25
View File
@@ -1,29 +1,9 @@
import type {ActivityStats, CursorPaginatedResponse, PaginatedResponse} from '@plunk/types';
import useSWR from 'swr';
export interface ActivityStats {
totalEvents: number;
totalEmailsSent: number;
totalEmailsOpened: number;
totalEmailsClicked: number;
totalWorkflowsStarted: number;
openRate: number;
clickRate: number;
}
export interface ContactsResponse {
contacts: unknown[];
total: number;
cursor?: string;
hasMore: boolean;
}
export interface CampaignsResponse {
campaigns: unknown[];
total: number;
page: number;
pageSize: number;
totalPages: number;
}
// Specific response types for dashboard (using unknown[] since we only need counts)
type ContactsResponse = CursorPaginatedResponse<unknown>;
type CampaignsResponse = PaginatedResponse<unknown>;
export interface DashboardStats {
totalContacts: number;
@@ -46,7 +26,7 @@ export function useDashboardStats(): DashboardStats {
const {data: contactsData, error: contactsError, isLoading: isLoadingContacts} = useSWR<ContactsResponse>('/contacts?limit=1');
// Fetch campaigns (only need the total count)
const {data: campaignsData, error: campaignsError, isLoading: isLoadingCampaigns} = useSWR<CampaignsResponse>('/campaigns?pageSize=1');
const {data: campaignsData, error: campaignsError, isLoading: isLoadingCampaigns} = useSWR<CampaignsResponse>('/campaigns?page=1&limit=1');
// Still loading if ANY of the requests are still in progress
const isLoading = isLoadingActivity || isLoadingContacts || isLoadingCampaigns;
+2 -11
View File
@@ -1,18 +1,9 @@
import type {Domain} from '@plunk/db';
import {DomainSchemas} from '@plunk/shared';
import useSWR from 'swr';
import {DomainSchemas} from '@plunk/shared';
import {network} from '../network';
export interface Domain {
id: string;
domain: string;
verified: boolean;
dkimTokens: string[] | null;
projectId: string;
createdAt: string;
updatedAt: string;
}
export interface DomainVerificationStatus {
domain: string;
tokens: string[];