Package Exports
- @bigdigital/kiosk-content-sdk
- @bigdigital/kiosk-content-sdk/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bigdigital/kiosk-content-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
npm install @bigdigital/kiosk-content-sdk
## Basic Usage
```typescript
import { useKioskContent } from '@bigdigital/kiosk-content-sdk';
function App() {
const config = {
projectId: process.env.VITE_FIREBASE_PROJECT_ID,
apiKey: process.env.VITE_FIREBASE_API_KEY,
offlineSupport: true, // Enable offline support
cacheStrategy: "local", // Use local storage for caching
syncInterval: 300000, // Sync every 5 minutes
cacheMaxAge: 600000 // Cache expires after 10 minutes
};
const { content, loading, error, isSyncing, isOnline } = useKioskContent(config);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{isSyncing && <div>Syncing...</div>}
{content.map(item => (
<div key={item.id}>
<h2>{item.title}</h2>
<p>{item.description}</p>
</div>
))}
</div>
);
}
Content Management
Retrieving Content by ID
Use useContent
hook to fetch and manage specific content items:
import { useContent } from '@bigdigital/kiosk-content-sdk';
function ContentViewer({ contentId }: { contentId: string }) {
const { content, loading, error, refresh } = useContent(contentId);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!content) return <div>Content not found</div>;
return (
<div>
<h1>{content.title}</h1>
<p>{content.description}</p>
{content.type === 'template' && (
<TemplateContent
values={content.templateValues}
templateId={content.templateId}
/>
)}
<button onClick={refresh}>Refresh Content</button>
</div>
);
}
Project-based Content Management
Filter and organize content by projects:
import { useProjectContent } from '@bigdigital/kiosk-content-sdk';
function ProjectContent({ projectId }: { projectId: string }) {
const {
content,
loading,
error,
filters,
setFilters,
pagination,
setPagination
} = useProjectContent(projectId, {
initialFilters: {
type: 'template',
status: 'published',
tags: ['featured']
},
initialPagination: {
page: 1,
limit: 10
}
});
return (
<div>
{/* Filter Controls */}
<div className="filters">
<select
value={filters.type}
onChange={e => setFilters(prev => ({ ...prev, type: e.target.value }))}
>
<option value="all">All Types</option>
<option value="template">Templates</option>
<option value="text">Text</option>
<option value="media">Media</option>
</select>
</div>
{/* Content List */}
{content.map(item => (
<ContentCard key={item.id} content={item} />
))}
{/* Pagination */}
<div className="pagination">
<button
onClick={() => setPagination(prev => ({
...prev,
page: prev.page - 1
}))}
disabled={pagination.page === 1}
>
Previous
</button>
<span>Page {pagination.page}</span>
<button
onClick={() => setPagination(prev => ({
...prev,
page: prev.page + 1
}))}
disabled={content.length < pagination.limit}
>
Next
</button>
</div>
</div>
);
}
Templates and Content Values
Working with Template-based Content
Templates define the structure of your content using fields organized into logical groups:
// Template structure
const template = {
id: "product-template",
name: "Product Template",
description: "Template for product content",
type: "product",
fields: {
"field-1": {
id: "field-1",
name: "productName",
label: "Product Name",
type: "text",
validation: { required: true }
},
"field-2": {
id: "field-2",
name: "price",
label: "Product Price",
type: "number",
validation: { required: true, min: 0 }
}
},
groups: {
"group-1": {
id: "group-1",
name: "Basic Info",
description: "Basic product information",
order: 1,
fieldIds: ["field-1", "field-2"]
}
},
groupOrder: ["group-1"],
ungroupedFieldIds: []
};
// Creating content with template values
const content = {
title: "Premium Widget",
description: "High-quality widget for professional use",
type: "template",
templateId: "product-template",
templateValues: {
groups: {
basicInfo: { // Note: Group names are in camelCase
productName: "Premium Widget Pro",
price: 299.99
}
},
ungrouped: {} // Values for fields not in any group
}
};
Rendering Template Content
function TemplateContent({ contentId }: { contentId: string }) {
const { content, template } = useTemplateContent(contentId);
if (!content || !template) return null;
return (
<div>
<h1>{content.title}</h1>
{/* Render grouped fields */}
{template.groupOrder.map(groupId => {
const group = template.groups[groupId];
if (!group) return null;
// Get fields for this group
const groupFields = group.fieldIds
.map(fieldId => template.fields[fieldId])
.filter(Boolean);
// Get values using camelCase group name
const groupName = normalizeGroupName(group.name);
const groupValues = content.templateValues?.groups?.[groupName] || {};
return (
<section key={groupId}>
<h2>{group.name}</h2>
{groupFields.map(field => (
<div key={field.id}>
<label>{field.label}</label>
<div>{groupValues[field.name]}</div>
</div>
))}
</section>
);
})}
</div>
);
}
Components
OfflineIndicator
A customizable component to display the current online/offline status:
import { useKioskContent, OfflineIndicator } from '@bigdigital/kiosk-content-sdk';
function App() {
const { isOnline } = useKioskContent(config);
return (
<div>
<OfflineIndicator
isOnline={isOnline}
onlineText="Connected" // Optional custom text
offlineText="Working Offline" // Optional custom text
className="my-custom-class" // Optional CSS class
style={{ position: 'fixed', top: '1rem', right: '1rem' }} // Optional inline styles
/>
{/* Rest of your app */}
</div>
);
}
Configuration Options
KioskConfig
interface KioskConfig {
projectId: string;
apiKey: string;
authDomain?: string;
offlineSupport?: boolean;
cacheStrategy?: "memory" | "local" | "none";
syncInterval?: number; // in milliseconds
cacheMaxAge?: number; // in milliseconds, defaults to 5 minutes
projectDefaults?: {
filterDefaults?: Record<string, any>;
paginationDefaults?: {
limit: number;
orderBy?: string;
orderDirection?: 'asc' | 'desc';
};
};
}
Offline Support
The SDK provides robust offline support with intelligent synchronization:
import { useOfflineContent } from '@bigdigital/kiosk-content-sdk';
function OfflineApp() {
const {
content,
syncStatus,
lastSynced,
error,
forceSyncContent
} = useOfflineContent({
projectId: "your-project-id",
apiKey: "your-api-key",
offlineSupport: true,
cacheStrategy: "local",
syncInterval: 300000,
cacheMaxAge: 600000
});
return (
<div>
<div className="sync-status">
<span>Status: {syncStatus}</span>
{lastSynced && (
<span>Last Synced: {new Date(lastSynced).toLocaleString()}</span>
)}
<button onClick={forceSyncContent}>
Force Sync
</button>
</div>
{error && <div className="error">Error: {error.message}</div>}
<div className="content">
{content.map(item => (
<ContentCard
key={item.id}
content={item}
isOffline={!navigator.onLine}
/>
))}
</div>
</div>
);
}