@pakt/collection-module
v0.0.4
Published
Collection management module for Pakt applications
Readme
@pakt/collection-module
A comprehensive React collection management module for Pakt applications. This package provides a complete solution for managing collection schemas and collections with full CRUD operations, filtering, and state management using React Query.
Features
- React Query Integration: Built on
@tanstack/react-queryfor powerful caching, synchronization, and state management - Collection Schema Management: Create, read, update, and delete collection schemas
- Collection Store Management: Full CRUD operations for collections within schemas
- Automatic Cache Management: React Query handles cache invalidation and refetching automatically
- TypeScript Support: Full type definitions included
- Filtering & Pagination: Built-in support for filtering and querying collections
- Error Handling: Comprehensive error handling with user-friendly messages
- Loading States: Built-in loading state management via React Query
- Customizable UI: Theme customization support
Installation
yarn add @pakt/collection-module @tanstack/react-query
# or
npm install @pakt/collection-module @tanstack/react-query
# or
bun add @pakt/collection-module @tanstack/react-queryNote: @tanstack/react-query is a peer dependency and must be installed separately.
Quick Start
Using React Query Hooks (Recommended)
import React from 'react';
import { PaktCollectionProvider, useCollections, useSchemas } from '@pakt/collection-module';
import '@pakt/collection-module/dist/styles.css';
function App() {
const config = {
baseUrl: "https://api-devpaktbuild.chain.site",
verbose: true,
};
return (
<PaktCollectionProvider config={config}>
<CollectionDemo />
</PaktCollectionProvider>
);
}
function CollectionDemo() {
const schemaReference = "person-profile"; // Your schema reference
// Use React Query hooks
const { useSchemasQuery } = useSchemas();
const { useCollectionsQuery, createCollection, updateCollection, deleteCollection } = useCollections(schemaReference);
const schemasQuery = useSchemasQuery();
const collectionsQuery = useCollectionsQuery();
// Access data, loading, and error states
const schemas = schemasQuery.data?.data?.schemas || [];
const collections = collectionsQuery.data?.data?.data || [];
if (schemasQuery.isLoading) return <div>Loading schemas...</div>;
if (collectionsQuery.isLoading) return <div>Loading collections...</div>;
if (schemasQuery.error) return <div>Error: {schemasQuery.error.message}</div>;
const handleCreate = () => {
createCollection.mutate({
firstName: "John",
email: "[email protected]",
// ... other fields
});
};
return (
<div>
<h1>Schemas</h1>
{schemas.map(schema => (
<div key={schema._id}>
<h2>{schema.name}</h2>
<p>{schema.description}</p>
</div>
))}
<h1>Collections</h1>
<button onClick={handleCreate}>Create Collection</button>
{collections.map(collection => (
<div key={collection._id}>
{/* Render collection data */}
</div>
))}
</div>
);
}Configuration
ConfigContextType
The main configuration object for the PaktCollectionProvider:
interface ConfigContextType {
baseUrl: string; // Required: API base URL
testnet?: boolean; // Optional: Use testnet environment
verbose?: boolean; // Optional: Enable verbose logging
theme?: ITheme; // Optional: Theme customization
}Theme Configuration
Customize the appearance of the collection components with semantic color tokens:
interface ITheme {
// Brand Colors
brandPrimary?: string; // Main brand color for buttons, links, icons
brandSecondary?: string; // Secondary brand color for backgrounds
// Text Colors
headingText?: string; // Color for headings and titles
bodyText?: string; // Color for body text and descriptions
inverseText?: string; // White text for dark backgrounds
// Background Colors
formBackground?: string; // Background color for forms and cards
modalOverlay?: string; // Overlay color for modals and dialogs
// Interactive Elements
buttonPrimaryBackground?: string; // Primary button background (supports gradients)
buttonPrimaryText?: string; // Primary button text color
buttonPrimaryHover?: string; // Primary button hover state
buttonOutlineBackground?: string; // Outline button background
buttonOutlineText?: string; // Outline button text color
// Form Input Colors
inputBackground?: string; // Input field background
inputBorder?: string; // Input field border
inputFocusBorder?: string; // Input field focus border
inputPlaceholder?: string; // Input placeholder text
inputText?: string; // Input text color
// State Colors
errorBackground?: string; // Error state background
errorText?: string; // Error state text
successText?: string; // Success state text
}Example:
const config: ConfigContextType = {
baseUrl: "https://api-devpaktbuild.chain.site",
theme: {
brandPrimary: "#007C5B",
buttonPrimaryBackground: "linear-gradient(102.28deg, #008D6C 32.23%, #11FFC7 139.92%)",
formBackground: "#FFFFFF",
errorText: "#DC2626",
},
};React Query Hooks
useSchemas Hook
The useSchemas hook provides React Query hooks for schema operations:
import { useSchemas } from '@pakt/collection-module';
function MyComponent() {
const {
useSchemasQuery, // Query hook for fetching schemas
useSchemaById, // Query hook for fetching a single schema
createSchema, // Mutation for creating a schema
updateSchema, // Mutation for updating a schema
deleteSchema, // Mutation for deleting a schema
} = useSchemas();
// Use the query hook
const schemasQuery = useSchemasQuery({ limit: 10 });
// Access data, loading, and error states
const schemas = schemasQuery.data?.data?.schemas || [];
const isLoading = schemasQuery.isLoading;
const error = schemasQuery.error;
// Use mutations
const handleCreate = () => {
createSchema.mutate({
name: "My Schema",
reference: "my-schema",
description: "Schema description",
}, {
onSuccess: (data) => {
console.log("Schema created:", data);
},
onError: (error) => {
console.error("Error:", error);
},
});
};
return (
<div>
{isLoading && <div>Loading...</div>}
{error && <div>Error: {error.message}</div>}
{schemas.map(schema => (
<div key={schema._id}>{schema.name}</div>
))}
<button onClick={handleCreate}>Create Schema</button>
</div>
);
}useCollections Hook
The useCollections hook provides React Query hooks for collection operations. It requires a schemaReference parameter:
import { useCollections } from '@pakt/collection-module';
function MyComponent() {
const schemaReference = "person-profile";
const {
useCollectionsQuery, // Query hook for fetching collections
getCountQuery, // Query hook for fetching collection count
useCollectionById, // Query hook for fetching a single collection
createCollection, // Mutation for creating a collection
updateCollection, // Mutation for updating a collection
deleteCollection, // Mutation for deleting a collection
} = useCollections(schemaReference);
// Use query hooks
const collectionsQuery = useCollectionsQuery({ limit: 20 });
const countQuery = getCountQuery;
const singleCollectionQuery = useCollectionById("collection-id");
// Access data
const collections = collectionsQuery.data?.data?.data || [];
const count = countQuery.data?.data || 0;
// Use mutations
const handleCreate = () => {
createCollection.mutate({
firstName: "John",
email: "[email protected]",
dateOfBirth: "1990-01-01",
}, {
onSuccess: () => {
// Cache is automatically invalidated and refetched
console.log("Collection created!");
},
});
};
const handleUpdate = (id: string) => {
updateCollection.mutate({
id,
payload: {
firstName: "Jane",
},
});
};
const handleDelete = (id: string) => {
deleteCollection.mutate(id, {
onSuccess: () => {
console.log("Collection deleted!");
},
});
};
return (
<div>
<p>Total collections: {count}</p>
{collections.map(collection => (
<div key={collection._id}>
<button onClick={() => handleUpdate(collection._id)}>Update</button>
<button onClick={() => handleDelete(collection._id)}>Delete</button>
</div>
))}
<button onClick={handleCreate}>Create Collection</button>
</div>
);
}Hook API Reference
useSchemas()
Returns React Query hooks and mutations for schema operations.
Returns:
{
useSchemasQuery: (filter?: filterCollectionSchemaDto) => UseQueryResult<ResponseDto<FindCollectionSchemaDto>>;
useSchemaById: (id: string) => UseQueryResult<ResponseDto<ICollectionSchemaDto>>;
createSchema: UseMutationResult<ResponseDto<ICollectionSchemaDto>, Error, CreateCollectionSchemaDto>;
updateSchema: UseMutationResult<ResponseDto<ICollectionSchemaDto>, Error, { id: string; payload: UpdateCollectionSchemaDto }>;
deleteSchema: UseMutationResult<ResponseDto<object>, Error, string>;
}useCollections(schemaReference: string)
Returns React Query hooks and mutations for collection operations.
Parameters:
schemaReference(string, required): The reference of the schema to work with
Returns:
{
useCollectionsQuery: (filter?: filterCollectionStoreDto) => UseQueryResult<ResponseDto<FindCollectionStoreDto>>;
getCountQuery: UseQueryResult<ResponseDto<number>>;
useCollectionById: (id: string) => UseQueryResult<ResponseDto<ICollectionStoreDto>>;
createCollection: UseMutationResult<ResponseDto<ICollectionStoreDto>, Error, CreateCollectionStoreDto>;
updateCollection: UseMutationResult<ResponseDto<ICollectionStoreDto>, Error, { id: string; payload: UpdateCollectionStoreDto }>;
deleteCollection: UseMutationResult<ResponseDto<object>, Error, string>;
}Usage Examples
Complete Example with React Query
import React, { useState } from 'react';
import { PaktCollectionProvider, useSchemas, useCollections } from '@pakt/collection-module';
function App() {
return (
<PaktCollectionProvider
config={{
baseUrl: "https://api-devpaktbuild.chain.site",
verbose: true,
}}
>
<CollectionManager />
</PaktCollectionProvider>
);
}
function CollectionManager() {
const [selectedSchemaRef, setSelectedSchemaRef] = useState<string>("");
const { useSchemasQuery, createSchema } = useSchemas();
const schemasQuery = useSchemasQuery();
const schemas = schemasQuery.data?.data?.schemas || [];
return (
<div>
<h1>Schemas</h1>
{schemas.map(schema => (
<div
key={schema._id}
onClick={() => setSelectedSchemaRef(schema.reference)}
>
<h2>{schema.name}</h2>
<p>{schema.description}</p>
</div>
))}
{selectedSchemaRef && (
<CollectionList schemaReference={selectedSchemaRef} />
)}
</div>
);
}
function CollectionList({ schemaReference }: { schemaReference: string }) {
const {
useCollectionsQuery,
getCountQuery,
createCollection,
updateCollection,
deleteCollection,
} = useCollections(schemaReference);
const collectionsQuery = useCollectionsQuery();
const countQuery = getCountQuery;
const collections = collectionsQuery.data?.data?.data || [];
const count = countQuery.data?.data || 0;
const handleCreate = () => {
createCollection.mutate({
// Your collection data based on schema
field1: "value1",
field2: "value2",
});
};
return (
<div>
<h2>Collections ({count})</h2>
<button onClick={handleCreate}>Create Collection</button>
{collectionsQuery.isLoading && <div>Loading...</div>}
{collectionsQuery.error && (
<div>Error: {collectionsQuery.error.message}</div>
)}
{collections.map(collection => (
<div key={collection._id}>
<pre>{JSON.stringify(collection, null, 2)}</pre>
<button
onClick={() => updateCollection.mutate({
id: collection._id,
payload: { field1: "updated" },
})}
>
Update
</button>
<button
onClick={() => deleteCollection.mutate(collection._id)}
>
Delete
</button>
</div>
))}
</div>
);
}Authentication Token Management
The hooks automatically read the authentication token from localStorage using the key pakt_auth_token. Set the token before using the hooks:
// Set the token
localStorage.setItem("pakt_auth_token", "your-auth-token");
// The hooks will automatically use this token
const { useSchemasQuery } = useSchemas();
const schemasQuery = useSchemasQuery();Query Filtering
Both hooks support filtering:
// Filter schemas
const schemasQuery = useSchemasQuery({
limit: 10,
page: 1,
});
// Filter collections
const collectionsQuery = useCollectionsQuery({
limit: 20,
offset: 0,
});Cache Management
React Query automatically manages cache invalidation. When mutations succeed, related queries are automatically invalidated and refetched:
const { createCollection } = useCollections(schemaReference);
// After this mutation succeeds, all collection queries are automatically refetched
createCollection.mutate(payload, {
onSuccess: () => {
// Cache is already invalidated and refetched automatically
console.log("Done!");
},
});Component Props
PaktCollectionProvider Props
interface PaktCollectionProps {
config: ConfigContextType; // Required: Configuration object
textConfig?: CollectionTextConfig; // Optional: Custom text configuration
onSchemaCreated?: (schema: ICollectionSchemaDto) => void; // Optional: Schema created callback
onSchemaUpdated?: (schema: ICollectionSchemaDto) => void; // Optional: Schema updated callback
onSchemaDeleted?: (schemaId: string) => void; // Optional: Schema deleted callback
onCollectionCreated?: (collection: ICollectionStoreDto) => void; // Optional: Collection created callback
onCollectionUpdated?: (collection: ICollectionStoreDto) => void; // Optional: Collection updated callback
onCollectionDeleted?: (collectionId: string) => void; // Optional: Collection deleted callback
}Note: The PaktCollectionProvider automatically includes a QueryClientProvider with a pre-configured QueryClient, so you don't need to set up React Query yourself. Just wrap your app with PaktCollectionProvider and start using the hooks!
Response Format
All methods return a ResponseDto<T> object:
interface ResponseDto<T> {
status: "success" | "error";
message: string;
data: T;
statusCode?: number;
code?: number;
}Schema Response Example:
{
status: "success",
message: "OK",
data: {
schemas: [...],
total: 1,
page: 1,
limit: 12
},
code: 200
}Collection Response Example:
{
status: "success",
message: "OK",
data: {
data: [...collections],
total: 100,
page: 1,
limit: 20
},
code: 200
}Types
Collection Schema Types
interface ICollectionSchemaDto {
_id: string;
name: string;
reference: string;
description?: string;
schema: SchemaField[];
access: {
read: string;
write: string;
};
createdAt: string;
updatedAt: string;
}
interface CreateCollectionSchemaDto {
name: string;
reference: string;
description?: string;
schema: SchemaField[];
access?: {
read: string;
write: string;
};
}
interface UpdateCollectionSchemaDto {
name?: string;
description?: string;
schema?: SchemaField[];
access?: {
read?: string;
write?: string;
};
}Collection Store Types
interface ICollectionStoreDto {
_id: string;
// Dynamic fields based on schema
[key: string]: any;
}
interface CreateCollectionStoreDto {
// Dynamic fields based on schema
[key: string]: any;
}
interface UpdateCollectionStoreDto {
// Dynamic fields to update
[key: string]: any;
}Legacy Context-Based Hook (Alternative)
For backward compatibility, the module also exports a context-based hook usePaktCollectionInternal. However, the React Query hooks (useCollections and useSchemas) are recommended for new projects as they provide better caching, synchronization, and state management.
PAKT SDK Integration
The module integrates with the PAKT SDK (@pakt/sdk) for backend collection management. The SDK handles:
- Collection schema CRUD operations
- Collection store CRUD operations
- Filtering and pagination
- Authentication token management
- Error handling and response formatting
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Contributing
Please refer to the CODE_OF_CONDUCT.md and LICENSE files.
License
MIT
