@23blocks/react 7.5.9 → 7.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +189 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -224,6 +224,7 @@ export function ProductList() {
224
224
  |------|-------------|
225
225
  | `useSearch()` | Search with state management |
226
226
  | `useFavorites()` | Favorites management |
227
+ | `useContentSeries()` | Content series management |
227
228
  | `useUsers()` | User management (admin) |
228
229
  | `useMfa()` | Multi-factor authentication |
229
230
  | `useOAuth()` | OAuth operations |
@@ -449,6 +450,194 @@ export function FavoriteButton({ itemId, itemType }: Props) {
449
450
  }
450
451
  ```
451
452
 
453
+ ### useContentSeries
454
+
455
+ Manage content series (collections of ordered posts like tutorials or courses).
456
+
457
+ ```tsx
458
+ 'use client';
459
+
460
+ import { useContentSeries } from '@23blocks/react';
461
+ import { useEffect } from 'react';
462
+
463
+ export function SeriesList() {
464
+ const {
465
+ series,
466
+ totalRecords,
467
+ isLoading,
468
+ error,
469
+ listSeries,
470
+ createSeries,
471
+ likeSeries,
472
+ } = useContentSeries();
473
+
474
+ useEffect(() => {
475
+ listSeries({ page: 1, perPage: 10 });
476
+ }, [listSeries]);
477
+
478
+ if (isLoading) return <div>Loading...</div>;
479
+ if (error) return <div>Error: {error.message}</div>;
480
+
481
+ return (
482
+ <div>
483
+ <p>Total: {totalRecords} series</p>
484
+ <ul>
485
+ {series.map((s) => (
486
+ <li key={s.uniqueId}>
487
+ <h3>{s.title}</h3>
488
+ <p>{s.description}</p>
489
+ <span>Posts: {s.postsCount} | Likes: {s.likes}</span>
490
+ <button onClick={() => likeSeries(s.uniqueId)}>Like</button>
491
+ </li>
492
+ ))}
493
+ </ul>
494
+ </div>
495
+ );
496
+ }
497
+ ```
498
+
499
+ #### Create a Series
500
+
501
+ ```tsx
502
+ 'use client';
503
+
504
+ import { useContentSeries } from '@23blocks/react';
505
+
506
+ export function CreateSeriesForm() {
507
+ const { createSeries, isLoading, error } = useContentSeries();
508
+
509
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
510
+ e.preventDefault();
511
+ const formData = new FormData(e.currentTarget);
512
+
513
+ const newSeries = await createSeries({
514
+ title: formData.get('title') as string,
515
+ description: formData.get('description') as string,
516
+ visibility: 'public',
517
+ completionStatus: 'ongoing',
518
+ });
519
+
520
+ console.log('Created series:', newSeries.uniqueId);
521
+ };
522
+
523
+ return (
524
+ <form onSubmit={handleSubmit}>
525
+ <input name="title" placeholder="Series Title" required />
526
+ <textarea name="description" placeholder="Description" />
527
+ <button type="submit" disabled={isLoading}>
528
+ {isLoading ? 'Creating...' : 'Create Series'}
529
+ </button>
530
+ {error && <p>Error: {error.message}</p>}
531
+ </form>
532
+ );
533
+ }
534
+ ```
535
+
536
+ #### Manage Series Posts
537
+
538
+ ```tsx
539
+ 'use client';
540
+
541
+ import { useContentSeries } from '@23blocks/react';
542
+ import { useEffect } from 'react';
543
+
544
+ export function SeriesPostManager({ seriesId }: { seriesId: string }) {
545
+ const {
546
+ posts,
547
+ currentSeries,
548
+ getSeries,
549
+ getSeriesPosts,
550
+ addSeriesPost,
551
+ removeSeriesPost,
552
+ reorderSeriesPosts,
553
+ isLoading,
554
+ } = useContentSeries();
555
+
556
+ useEffect(() => {
557
+ getSeries(seriesId);
558
+ getSeriesPosts(seriesId);
559
+ }, [seriesId, getSeries, getSeriesPosts]);
560
+
561
+ const handleAddPost = async (postId: string) => {
562
+ await addSeriesPost(seriesId, postId);
563
+ await getSeriesPosts(seriesId); // Refresh
564
+ };
565
+
566
+ const handleRemovePost = async (postId: string) => {
567
+ await removeSeriesPost(seriesId, postId);
568
+ };
569
+
570
+ const handleReorder = async () => {
571
+ await reorderSeriesPosts(seriesId, {
572
+ posts: posts.map((p, idx) => ({
573
+ postUniqueId: p.uniqueId,
574
+ sequence: idx + 1,
575
+ })),
576
+ });
577
+ };
578
+
579
+ return (
580
+ <div>
581
+ <h2>{currentSeries?.title}</h2>
582
+ <p>{posts.length} posts in this series</p>
583
+ <ul>
584
+ {posts.map((post, idx) => (
585
+ <li key={post.uniqueId}>
586
+ {idx + 1}. {post.title}
587
+ <button onClick={() => handleRemovePost(post.uniqueId)}>
588
+ Remove
589
+ </button>
590
+ </li>
591
+ ))}
592
+ </ul>
593
+ <button onClick={handleReorder} disabled={isLoading}>
594
+ Save Order
595
+ </button>
596
+ </div>
597
+ );
598
+ }
599
+ ```
600
+
601
+ #### useContentSeries Return Type
602
+
603
+ ```typescript
604
+ interface UseContentSeriesReturn {
605
+ // State
606
+ series: Series[]; // List of series
607
+ currentSeries: Series | null; // Currently loaded series
608
+ posts: Post[]; // Posts in current series
609
+ totalRecords: number; // Total series count
610
+ isLoading: boolean; // Loading state
611
+ error: Error | null; // Error state
612
+
613
+ // CRUD Operations
614
+ listSeries(params?: ListSeriesParams): Promise<PageResult<Series>>;
615
+ querySeries(params: QuerySeriesParams): Promise<PageResult<Series>>;
616
+ getSeries(uniqueId: string): Promise<Series>;
617
+ createSeries(data: CreateSeriesRequest): Promise<Series>;
618
+ updateSeries(uniqueId: string, data: UpdateSeriesRequest): Promise<Series>;
619
+ deleteSeries(uniqueId: string): Promise<void>;
620
+
621
+ // Social Actions
622
+ likeSeries(uniqueId: string): Promise<Series>;
623
+ dislikeSeries(uniqueId: string): Promise<Series>;
624
+ followSeries(uniqueId: string): Promise<Series>;
625
+ unfollowSeries(uniqueId: string): Promise<void>;
626
+ saveSeries(uniqueId: string): Promise<Series>;
627
+ unsaveSeries(uniqueId: string): Promise<void>;
628
+
629
+ // Post Management
630
+ getSeriesPosts(uniqueId: string): Promise<Post[]>;
631
+ addSeriesPost(seriesId: string, postId: string, sequence?: number): Promise<void>;
632
+ removeSeriesPost(seriesId: string, postId: string): Promise<void>;
633
+ reorderSeriesPosts(uniqueId: string, data: ReorderPostsRequest): Promise<Series>;
634
+
635
+ // State Management
636
+ clearSeries(): void;
637
+ clearError(): void;
638
+ }
639
+ ```
640
+
452
641
  ## Server-Side Rendering (SSR)
453
642
 
454
643
  ### Handling Client-Only Code
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@23blocks/react",
3
- "version": "7.5.9",
3
+ "version": "7.5.11",
4
4
  "description": "React bindings for 23blocks SDK - hooks and context providers",
5
5
  "license": "MIT",
6
6
  "author": "23blocks <hello@23blocks.com>",