@nice2dev/events 1.0.29 → 1.1.5

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.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { default as default_2 } from 'react';
7
+ import { NiceHtmlEditorCommand } from '@nice2dev/ui';
7
8
 
8
9
  /** Attraction category. */
9
10
  export declare type AttractionCategory = 'game' | 'music' | 'dance' | 'quiz' | 'karaoke' | 'photo' | 'custom';
@@ -17,7 +18,16 @@ export declare interface BillingItem {
17
18
  paidById?: string;
18
19
  paidByName?: string;
19
20
  splitAmong?: string[];
21
+ /**
22
+ * Paid to the vendor — **not** settled between participants.
23
+ *
24
+ * Deliberately has no effect on balances: letting it zero one would erase
25
+ * everyone's debt the moment somebody pays the caterer. Settling up between
26
+ * people is recorded separately, as {@link NiceSettlementTransfer}[].
27
+ */
20
28
  isPaid?: boolean;
29
+ /** When the expense was incurred (ISO). Orders the expense list. */
30
+ incurredAt?: string;
21
31
  }
22
32
 
23
33
  export declare interface CateringZone {
@@ -57,6 +67,12 @@ export declare interface ChatMessage {
57
67
  /** Chat message type. */
58
68
  export declare type ChatMessageType = 'text' | 'image' | 'system' | 'reaction' | 'announcement';
59
69
 
70
+ /** Rendered size of the chart container, in CSS pixels. */
71
+ declare interface ContainerSize {
72
+ width: number;
73
+ height: number;
74
+ }
75
+
60
76
  export declare interface EvacuationPlan {
61
77
  venueId: string;
62
78
  routes: EvacuationRoute[];
@@ -108,6 +124,17 @@ export declare interface EventAttraction {
108
124
  order?: number;
109
125
  }
110
126
 
127
+ /** Attached document (Documents tab). */
128
+ export declare interface EventDocument {
129
+ id: string;
130
+ name: string;
131
+ fileType?: string;
132
+ url?: string;
133
+ sizeKb?: number;
134
+ uploadedByName?: string;
135
+ uploadedAt?: string;
136
+ }
137
+
111
138
  /** Event location. */
112
139
  export declare interface EventLocation {
113
140
  name: string;
@@ -130,6 +157,12 @@ export declare interface EventMediaItem {
130
157
  caption?: string;
131
158
  likes?: number;
132
159
  tags?: string[];
160
+ /**
161
+ * Display position. Items sort by `order`, falling back to their index in
162
+ * the `items` array. Order is controlled by the caller: components emit
163
+ * `onReorder` and never hold their own copy of the sequence.
164
+ */
165
+ order?: number;
133
166
  }
134
167
 
135
168
  /** Core event model. */
@@ -170,7 +203,7 @@ export declare interface EventParticipant {
170
203
  declare type EventPlanningDisplayMode = 'micro' | 'compact' | 'normal' | 'full';
171
204
 
172
205
  /** Available planner tabs. */
173
- declare type EventPlanningTab = 'details' | 'location' | 'participants' | 'surveys' | 'budget' | 'settings';
206
+ declare type EventPlanningTab = 'details' | 'location' | 'schedule' | 'participants' | 'tasks' | 'surveys' | 'vendors' | 'budget' | 'documents' | 'settings';
174
207
 
175
208
  /** Event round. */
176
209
  export declare interface EventRound {
@@ -251,6 +284,32 @@ export declare interface EventSurvey {
251
284
  isActive?: boolean;
252
285
  }
253
286
 
287
+ /** Planning task / checklist item (Tasks tab). */
288
+ export declare interface EventTask {
289
+ id: string;
290
+ title: string;
291
+ done?: boolean;
292
+ assigneeName?: string;
293
+ dueDate?: string;
294
+ }
295
+
296
+ /** Vendor / supplier (Vendors tab). */
297
+ export declare interface EventVendor {
298
+ id: string;
299
+ name: string;
300
+ category?: string;
301
+ contact?: string;
302
+ status?: 'contacted' | 'quoted' | 'booked' | 'confirmed' | 'cancelled';
303
+ cost?: number;
304
+ currency?: string;
305
+ }
306
+
307
+ /** How the expense list is ordered. */
308
+ export declare type ExpenseSortBy = 'date' | 'amount' | 'none';
309
+
310
+ /** Which of the three views is showing. */
311
+ export declare type ExpenseSplitView = 'expenses' | 'balances' | 'settlement';
312
+
254
313
  export declare interface FloorPlanUpsellConfig {
255
314
  /** Show "Add Floor Plan" button */
256
315
  showButton: boolean;
@@ -264,6 +323,17 @@ export declare interface FloorPlanUpsellConfig {
264
323
  autoLinkAddress: boolean;
265
324
  }
266
325
 
326
+ /** What a guest is pledging. */
327
+ export declare interface GiftContributionPayload {
328
+ amount?: number;
329
+ quantity?: number;
330
+ message?: string;
331
+ /** Always present — anonymous guests type it in. */
332
+ userName: string;
333
+ /** Only when the contributor was signed in. */
334
+ userId?: string;
335
+ }
336
+
267
337
  /** Karaoke song with lyrics. */
268
338
  export declare interface KaraokeSong extends SongEntry {
269
339
  hasLyrics: boolean;
@@ -329,6 +399,16 @@ export declare interface NiceAttractionVotingProps {
329
399
  style?: default_2.CSSProperties;
330
400
  }
331
401
 
402
+ /** One tile in a collage or slideshow. */
403
+ export declare interface NiceCollageItem {
404
+ id: string;
405
+ mediaUrl: string;
406
+ type?: 'photo' | 'video';
407
+ caption?: string;
408
+ /** Slideshow dwell time for this tile; falls back to the collage default. */
409
+ durationMs?: number;
410
+ }
411
+
332
412
  /**
333
413
  * {@link NiceEventMedia} — responsive media gallery (photos / videos) built from
334
414
  * Nice* controls: NiceUpload for adding media and NiceCardGroup for the layout.
@@ -355,6 +435,16 @@ export declare interface NiceEventMediaProps {
355
435
  uploadEnabled?: boolean;
356
436
  /** Filter by type. */
357
437
  typeFilter?: 'photo' | 'video' | 'all';
438
+ /**
439
+ * Enables drag-to-reorder and is called with the full id sequence after a
440
+ * move. Order is controlled: items render sorted by `EventMediaItem.order`
441
+ * (falling back to array position) and this component never keeps its own
442
+ * copy of the sequence, so the view cannot drift from what was saved.
443
+ *
444
+ * Reordering applies to the whole list, so it is ignored while `typeFilter`
445
+ * hides part of it.
446
+ */
447
+ onReorder?: (orderedIds: string[]) => void;
358
448
  className?: string;
359
449
  style?: default_2.CSSProperties;
360
450
  }
@@ -377,6 +467,14 @@ export declare interface NiceEventPlanningProps {
377
467
  surveys?: EventSurvey[];
378
468
  /** Billing items (Budget tab). */
379
469
  billing?: BillingItem[];
470
+ /** Agenda entries (Schedule tab). */
471
+ scheduleItems?: ScheduleItem[];
472
+ /** Planning tasks / checklist (Tasks tab). */
473
+ tasks?: EventTask[];
474
+ /** Vendors / suppliers (Vendors tab). */
475
+ vendors?: EventVendor[];
476
+ /** Attached documents (Documents tab). */
477
+ documents?: EventDocument[];
380
478
  /**
381
479
  * Display density / scope. `micro` renders only a summary card (no tabs);
382
480
  * `compact` shows the core tabs; `normal` (default) and `full` show everything.
@@ -388,6 +486,35 @@ export declare interface NiceEventPlanningProps {
388
486
  activeTab?: EventPlanningTab;
389
487
  /** Active-tab change handler. */
390
488
  onTabChange?: (tab: EventPlanningTab) => void;
489
+ /** Show only the tab icons (labels in the tooltip). Default `true`. */
490
+ tabsIconOnly?: boolean;
491
+ /** Center the tab strip. `'auto'` (default) centers only when icon-only. */
492
+ tabsCentered?: boolean | 'auto';
493
+ /**
494
+ * Where per-tab counts sit relative to the icon: `'bottom'` (default) — a
495
+ * heavily-rounded pill under the icon; `'right'` — inline after the icon.
496
+ */
497
+ countLocation?: 'bottom' | 'right';
498
+ /** Show the Details tab (default `true`). */
499
+ showDetails?: boolean;
500
+ /** Show the Location tab (default `true`). */
501
+ showLocation?: boolean;
502
+ /** Show the Schedule tab (default `true`). */
503
+ showSchedule?: boolean;
504
+ /** Show the Participants tab (default `true`). */
505
+ showParticipants?: boolean;
506
+ /** Show the Tasks tab (default `true`). */
507
+ showTasks?: boolean;
508
+ /** Show the Surveys tab (default `true`). */
509
+ showSurveys?: boolean;
510
+ /** Show the Vendors tab (default `true`). */
511
+ showVendors?: boolean;
512
+ /** Show the Budget tab (default `true`). */
513
+ showBudget?: boolean;
514
+ /** Show the Documents tab (default `true`). */
515
+ showDocuments?: boolean;
516
+ /** Show the Settings tab (default `true`). */
517
+ showSettings?: boolean;
391
518
  /** Whether editing is allowed. */
392
519
  editable?: boolean;
393
520
  /** Toolbar — Save handler (button shown when provided). */
@@ -412,6 +539,246 @@ export declare interface NiceEventPlanningProps {
412
539
  style?: default_2.CSSProperties;
413
540
  }
414
541
 
542
+ /** A `BillingItem` that could not be included in the balance maths. */
543
+ export declare interface NiceExpenseIssue {
544
+ itemId: string;
545
+ reason: 'no-payer' | 'unknown-payer' | 'no-participants';
546
+ }
547
+
548
+ /**
549
+ * {@link NiceExpenseSplit} — who paid, who owes, and the shortest way to square up.
550
+ *
551
+ * Three views over the same data: the expense list, each person's net balance,
552
+ * and a settlement plan that reduces the debt graph to few transfers (at most
553
+ * one less than the number of people who owe or are owed). The plan is not
554
+ * provably minimal — exact minimisation is NP-hard — but it is what every
555
+ * comparable product ships and it is optimal in ordinary cases.
556
+ *
557
+ * Arithmetic runs on integer minor units, so balances sum to exactly zero and
558
+ * no rounding drifts. Expenses in different currencies are grouped and settled
559
+ * separately rather than converted: applying an exchange rate silently at
560
+ * render time would be a correctness bug, and this package has no business
561
+ * owning FX rates.
562
+ *
563
+ * `BillingItem.isPaid` does not affect balances — it records that the vendor
564
+ * was paid, not that the group settled up.
565
+ */
566
+ export declare const NiceExpenseSplit: default_2.ForwardRefExoticComponent<NiceExpenseSplitProps & default_2.RefAttributes<HTMLDivElement>>;
567
+
568
+ /** Props for {@link NiceExpenseSplit}. */
569
+ export declare interface NiceExpenseSplitProps {
570
+ /** Expenses, using the existing `BillingItem` shape. */
571
+ items: BillingItem[];
572
+ /** Everyone who can pay or owe. */
573
+ participants: Array<{
574
+ id: string;
575
+ name: string;
576
+ avatarUrl?: string;
577
+ }>;
578
+ /** Payments already made, subtracted before the plan is computed. */
579
+ settlements?: NiceSettlementTransfer[];
580
+ /** Which view to show. Leave unset to let the control manage it. */
581
+ view?: ExpenseSplitView;
582
+ defaultView?: ExpenseSplitView;
583
+ onViewChange?: (view: ExpenseSplitView) => void;
584
+ /** Called when a suggested transfer is marked as paid. */
585
+ onSettle?: (transfer: NiceSettlementTransfer) => void;
586
+ onItemDelete?: (itemId: string) => void;
587
+ onItemClick?: (item: BillingItem) => void;
588
+ /** Reports expenses that could not be included in the maths. */
589
+ onValidationChange?: (issues: NiceExpenseIssue[]) => void;
590
+ /**
591
+ * Order of the expense list. `'date'` sorts oldest first by
592
+ * `BillingItem.incurredAt`, leaving undated expenses at the end in the order
593
+ * they were given; `'none'` keeps the caller's order.
594
+ *
595
+ * Presentation only — balances and the settlement plan do not depend on it.
596
+ */
597
+ sortBy?: ExpenseSortBy;
598
+ /** Locale for money formatting. Defaults to the runtime locale. */
599
+ locale?: string;
600
+ disabled?: boolean;
601
+ readOnly?: boolean;
602
+ size?: 'sm' | 'md';
603
+ className?: string;
604
+ style?: default_2.CSSProperties;
605
+ }
606
+
607
+ /** A single contribution towards a gift registry item. */
608
+ export declare interface NiceGiftContribution {
609
+ id: string;
610
+ /** Display name. Always present — a guest with no account types it in. */
611
+ contributorName: string;
612
+ /** Set only when the contributor was a signed-in user. */
613
+ contributorUserId?: string;
614
+ /** Money contributed (group gifting). */
615
+ amount?: number;
616
+ /** Units contributed, when the item is counted rather than funded. */
617
+ quantity?: number;
618
+ message?: string;
619
+ /** ISO timestamp. */
620
+ contributedAt: string;
621
+ }
622
+
623
+ /**
624
+ * {@link NiceGiftRegistry} — a gift list guests can actually use: what is still
625
+ * needed, what is already covered, and a way to chip in.
626
+ *
627
+ * Two shapes behind one component, chosen with `kind`. A **registry** counts
628
+ * units and money towards each gift, so several people can share the cost of
629
+ * something expensive. A **wishlist** drops the money and tracks priority and
630
+ * whether the thing has been bought.
631
+ *
632
+ * Both work with no signed-in user, because the guest view is normally reached
633
+ * through a public share link: an anonymous guest types their name and that
634
+ * comes back as `userName` with no `userId`.
635
+ *
636
+ * `hideContributors` hides the names but keeps the progress bar — you can see
637
+ * a gift is covered without seeing who covered it.
638
+ */
639
+ export declare const NiceGiftRegistry: default_2.ForwardRefExoticComponent<NiceGiftRegistryProps & default_2.RefAttributes<HTMLDivElement>>;
640
+
641
+ /** An item on a gift registry or wishlist. */
642
+ export declare interface NiceGiftRegistryItem {
643
+ id: string;
644
+ title: string;
645
+ description?: string;
646
+ /** Link to a shop. */
647
+ url?: string;
648
+ imageUrl?: string;
649
+ price?: {
650
+ amount: number;
651
+ currency: string;
652
+ };
653
+ /** Units needed. Registry only; defaults to 1. */
654
+ quantityNeeded?: number;
655
+ /** Units already covered. Registry only. */
656
+ quantityContributed?: number;
657
+ contributions?: NiceGiftContribution[];
658
+ /** Wishlist only — higher sorts first. */
659
+ priority?: number;
660
+ /** Wishlist only. */
661
+ isPurchased?: boolean;
662
+ /** Wishlist only — who bought it, when known. */
663
+ purchasedByUserId?: string;
664
+ }
665
+
666
+ /** Props for {@link NiceGiftRegistry}. */
667
+ export declare interface NiceGiftRegistryProps {
668
+ /** Items on the list. */
669
+ items: NiceGiftRegistryItem[];
670
+ /**
671
+ * `registry` tracks quantities and money towards each gift; `wishlist` is
672
+ * the same list without the money — priority and a bought/not-bought flag.
673
+ *
674
+ * Named `kind` rather than `variant` because `variant` already means the
675
+ * colour intent across the library.
676
+ */
677
+ kind?: 'registry' | 'wishlist';
678
+ /** `owner` manages the list; `guest` is the public, read-mostly view. */
679
+ mode?: 'owner' | 'guest';
680
+ /** Fallback currency for items with no price of their own. */
681
+ currency?: string;
682
+ locale?: string;
683
+ /**
684
+ * Hide who contributed what. The progress bar stays — the classic wedding
685
+ * registry behaviour, where you can see a gift is covered without seeing
686
+ * who covered it.
687
+ */
688
+ hideContributors?: boolean;
689
+ /**
690
+ * Signed-in user. Leave unset for a public share-token page; guests are
691
+ * then asked for a name before they can pledge.
692
+ */
693
+ currentUserId?: string;
694
+ currentUserName?: string;
695
+ onContribute?: (itemId: string, payload: GiftContributionPayload) => void;
696
+ /** "I'll take this one" — reserving the whole item. */
697
+ onClaim?: (itemId: string, payload: GiftContributionPayload) => void;
698
+ onUnclaim?: (itemId: string) => void;
699
+ onItemAdd?: (item: Omit<NiceGiftRegistryItem, 'id' | 'quantityContributed'>) => void;
700
+ onItemDelete?: (itemId: string) => void;
701
+ onItemClick?: (item: NiceGiftRegistryItem) => void;
702
+ layout?: 'grid' | 'list';
703
+ disabled?: boolean;
704
+ readOnly?: boolean;
705
+ size?: 'sm' | 'md';
706
+ className?: string;
707
+ style?: default_2.CSSProperties;
708
+ }
709
+
710
+ /**
711
+ * {@link NiceInvitationDesigner} — write the invitation, see it as a guest will,
712
+ * and send it to a list.
713
+ *
714
+ * Split into an editor and a live preview. `{{token}}` placeholders are
715
+ * inserted from a row of buttons and resolved against `previewData` on the
716
+ * right, so you can check a real name lands where you meant it to. Substituted
717
+ * values are HTML-escaped — guest names are user input going into an HTML
718
+ * string.
719
+ *
720
+ * The recipient box is a textarea because the real workflow is pasting a
721
+ * column out of a spreadsheet: it splits on commas, semicolons, tabs and
722
+ * newlines, unwraps `Name <addr@example.com>`, and drops duplicates.
723
+ *
724
+ * `onSend` dispatches real mail, so pass `sending` while a send is in flight —
725
+ * the button stays disabled until you clear it.
726
+ */
727
+ export declare const NiceInvitationDesigner: default_2.ForwardRefExoticComponent<NiceInvitationDesignerProps & default_2.RefAttributes<HTMLDivElement>>;
728
+
729
+ /** Props for {@link NiceInvitationDesigner}. */
730
+ export declare interface NiceInvitationDesignerProps {
731
+ /** The template being edited. */
732
+ template: NiceInvitationTemplate;
733
+ onTemplateChange?: (template: NiceInvitationTemplate) => void;
734
+ /** Placeholders offered as insert buttons. */
735
+ tokens?: NiceInvitationToken[];
736
+ /** Values substituted into the live preview. */
737
+ previewData?: Record<string, string>;
738
+ recipients?: NiceInvitationRecipient[];
739
+ onRecipientsChange?: (emails: string[]) => void;
740
+ /** Called to actually send. Guard it with {@link sending}. */
741
+ onSend?: (payload: {
742
+ templateId?: string;
743
+ emails: string[];
744
+ }) => void;
745
+ /**
746
+ * A send is in flight. Blocks the button — this dispatches real mail, and a
747
+ * double click is a double send.
748
+ */
749
+ sending?: boolean;
750
+ /** Editor toolbar. Defaults to a subset suited to writing an invitation. */
751
+ toolbar?: NiceHtmlEditorCommand[];
752
+ disabled?: boolean;
753
+ readOnly?: boolean;
754
+ size?: 'sm' | 'md';
755
+ className?: string;
756
+ style?: default_2.CSSProperties;
757
+ }
758
+
759
+ /** One address on the send list. */
760
+ export declare interface NiceInvitationRecipient {
761
+ email: string;
762
+ name?: string;
763
+ status?: 'pending' | 'sent' | 'failed';
764
+ }
765
+
766
+ /** The invitation being written. */
767
+ export declare interface NiceInvitationTemplate {
768
+ id?: string;
769
+ name: string;
770
+ /** HTML body, with `{{token}}` placeholders. */
771
+ body: string;
772
+ coverImageUrl?: string;
773
+ }
774
+
775
+ /** A placeholder the host can insert with one click. */
776
+ export declare interface NiceInvitationToken {
777
+ key: string;
778
+ label: string;
779
+ sample?: string;
780
+ }
781
+
415
782
  /**
416
783
  * {@link NiceKaraokePicker} — Karaoke song picker with queue management.
417
784
  */
@@ -437,6 +804,120 @@ export declare interface NiceKaraokePickerProps {
437
804
  style?: default_2.CSSProperties;
438
805
  }
439
806
 
807
+ /**
808
+ * {@link NiceMediaCollage} — arrange photos and video into an ordered collage
809
+ * and play it back as a slideshow.
810
+ *
811
+ * The companion to `NiceEventMedia`: that one is for browsing what people
812
+ * uploaded, this one is for deciding what the montage looks like. Tiles are
813
+ * reordered by dragging or from the keyboard (focus a tile, Space to pick it
814
+ * up, arrows to move, Space to drop, Escape to cancel) — pointer events
815
+ * throughout, so it works on a phone.
816
+ *
817
+ * Order is controlled by the caller: the component sorts the `items` it is
818
+ * given and reports moves through `onReorder`.
819
+ */
820
+ export declare const NiceMediaCollage: default_2.ForwardRefExoticComponent<NiceMediaCollageProps & default_2.RefAttributes<HTMLDivElement>>;
821
+
822
+ /** Arrangement used by `NiceMediaCollage`. */
823
+ export declare type NiceMediaCollageLayout = 'sequence' | 'grid' | 'mosaic';
824
+
825
+ /** Props for {@link NiceMediaCollage}. */
826
+ export declare interface NiceMediaCollageProps {
827
+ /** Tiles, in the order they should appear. */
828
+ items: NiceCollageItem[];
829
+ /** Arrangement. `sequence` is a single ordered strip; the others are grids. */
830
+ layout?: NiceMediaCollageLayout;
831
+ /**
832
+ * Called with the full id sequence after a move. Order is controlled: the
833
+ * component never keeps its own copy, so the view cannot drift from what
834
+ * was persisted.
835
+ */
836
+ onReorder?: (orderedIds: string[]) => void;
837
+ onItemAdd?: (files: File[]) => void;
838
+ onItemRemove?: (id: string) => void;
839
+ onCaptionChange?: (id: string, caption: string) => void;
840
+ onItemClick?: (item: NiceCollageItem) => void;
841
+ /** Play the tiles as a slideshow instead of showing the editor. */
842
+ previewMode?: boolean;
843
+ transition?: 'none' | 'fade' | 'slide';
844
+ /** Dwell time per tile, unless the tile sets its own. Default `3000`. */
845
+ defaultDurationMs?: number;
846
+ /** Advance the slideshow automatically. Default `true` in preview. */
847
+ autoPlay?: boolean;
848
+ disabled?: boolean;
849
+ readOnly?: boolean;
850
+ size?: 'sm' | 'md';
851
+ className?: string;
852
+ style?: default_2.CSSProperties;
853
+ }
854
+
855
+ /** Net position of one participant in one currency. */
856
+ export declare interface NiceParticipantBalance {
857
+ participantId: string;
858
+ participantName: string;
859
+ /** Positive: owed to them. Negative: they owe. Zero: settled up. */
860
+ amount: number;
861
+ currency: string;
862
+ }
863
+
864
+ /**
865
+ * {@link NiceParticipantList} — the guest roster: who is coming, who replied,
866
+ * who has arrived.
867
+ *
868
+ * Two modes. `organizer` is the management view: counts, grouping, search,
869
+ * per-row RSVP and check-in, and an invite box that parses a pasted list of
870
+ * addresses. `guest` is the self-service view — only the viewer's own row,
871
+ * with {@link NiceRsvpControl} for answering.
872
+ *
873
+ * Check-in by QR is wired through `onScan` plus a `checkInSlot` you fill with
874
+ * your own scanner, so the package takes no camera dependency and your app
875
+ * keeps control of the permission prompt.
876
+ */
877
+ export declare const NiceParticipantList: default_2.ForwardRefExoticComponent<NiceParticipantListProps & default_2.RefAttributes<HTMLDivElement>>;
878
+
879
+ /** Props for {@link NiceParticipantList}. */
880
+ export declare interface NiceParticipantListProps {
881
+ /** The roster. */
882
+ participants: EventParticipant[];
883
+ /**
884
+ * `organizer` manages everyone; `guest` shows only the viewer's own entry
885
+ * with RSVP actions.
886
+ */
887
+ mode?: 'organizer' | 'guest';
888
+ /** Identifies the viewer's own row in `guest` mode. */
889
+ currentUserId?: string;
890
+ currentUserName?: string;
891
+ /** Called when a participant's RSVP changes. */
892
+ onRsvpChange?: (participantId: string, status: ParticipantStatus, selection?: NiceRsvpSelection) => void;
893
+ /** Called when a participant is checked in. */
894
+ onCheckIn?: (participantId: string) => void;
895
+ /**
896
+ * Called with a scanned code. Pair with {@link checkInSlot} to host your own
897
+ * scanner — this package does not take a camera dependency.
898
+ */
899
+ onScan?: (code: string) => void;
900
+ /** Your scanner UI, rendered in the toolbar when provided. */
901
+ checkInSlot?: default_2.ReactNode;
902
+ /** Called with parsed, de-duplicated addresses from the invite box. */
903
+ onInvite?: (emails: string[]) => void;
904
+ /** Extra columns. */
905
+ extraFields?: ParticipantExtraField[];
906
+ /** Group rows under headings. */
907
+ groupBy?: 'status' | 'role' | 'none';
908
+ /** Show the counts strip. */
909
+ showSummary?: boolean;
910
+ /** Show the filter/search row. */
911
+ showSearch?: boolean;
912
+ /** Offer plus-ones in guest mode. */
913
+ allowPlusOnes?: boolean;
914
+ disabled?: boolean;
915
+ readOnly?: boolean;
916
+ size?: 'sm' | 'md';
917
+ className?: string;
918
+ style?: default_2.CSSProperties;
919
+ }
920
+
440
921
  /**
441
922
  * {@link NiceRoundCard} — Individual round card with actions, timer, and scoreboard.
442
923
  */
@@ -491,6 +972,160 @@ export declare interface NiceRoundListProps {
491
972
  style?: default_2.CSSProperties;
492
973
  }
493
974
 
975
+ /** The three answers a guest can give to an invitation. */
976
+ export declare type NiceRsvpAnswer = 'yes' | 'maybe' | 'no';
977
+
978
+ /**
979
+ * {@link NiceRsvpControl} — yes / maybe / no, with optional plus-ones and a note.
980
+ *
981
+ * Small on purpose: it is meant to be dropped onto a public invitation page
982
+ * reached through a share link, so it never assumes a signed-in user. When
983
+ * `currentUserId` is absent the guest types their name, and `onRespond`
984
+ * reports it as `userName` with no `userId`.
985
+ *
986
+ * `NiceParticipantList` embeds this same control in its guest mode, so there
987
+ * is exactly one RSVP implementation in the package.
988
+ */
989
+ export declare const NiceRsvpControl: default_2.ForwardRefExoticComponent<NiceRsvpControlProps & default_2.RefAttributes<HTMLDivElement>>;
990
+
991
+ /** Props for {@link NiceRsvpControl}. */
992
+ export declare interface NiceRsvpControlProps {
993
+ /** Current answer, when the guest has already replied. */
994
+ value?: NiceRsvpAnswer;
995
+ /** Called when the guest commits a reply. */
996
+ onRespond?: (selection: NiceRsvpSelection) => void;
997
+ /** Offer a "+N guests" field. */
998
+ allowPlusOnes?: boolean;
999
+ /** Cap on additional guests. Default `5`. */
1000
+ maxPlusOnes?: number;
1001
+ /** Current number of additional guests. */
1002
+ plusOnes?: number;
1003
+ /** Offer a free-text note (dietary needs, arrival time…). */
1004
+ allowNote?: boolean;
1005
+ /**
1006
+ * Signed-in user. Leave unset for a public invitation page — the guest is
1007
+ * then asked for a name before they can reply.
1008
+ */
1009
+ currentUserId?: string;
1010
+ currentUserName?: string;
1011
+ /** Show only the answer buttons, without name, plus-ones or note. */
1012
+ compact?: boolean;
1013
+ disabled?: boolean;
1014
+ readOnly?: boolean;
1015
+ size?: 'sm' | 'md' | 'lg';
1016
+ className?: string;
1017
+ style?: default_2.CSSProperties;
1018
+ }
1019
+
1020
+ /** A guest's reply, including who replied and how many they bring. */
1021
+ export declare interface NiceRsvpSelection {
1022
+ answer: NiceRsvpAnswer;
1023
+ /** Additional guests beyond the responder. */
1024
+ plusOnes?: number;
1025
+ /** Display name — a guest arriving from a share link has no account. */
1026
+ userName?: string;
1027
+ userId?: string;
1028
+ note?: string;
1029
+ }
1030
+
1031
+ /**
1032
+ * {@link NiceSeatingChart} — pick seats from a venue plan, at any venue size.
1033
+ *
1034
+ * Renders SVG with three levels of detail chosen from how many seats are
1035
+ * actually in view: whole sections when zoomed out, row strips in between,
1036
+ * individual seats up close. Because the tier is decided *after* culling, a
1037
+ * 20 000-seat stadium and a 200-seat theatre both draw a bounded number of
1038
+ * nodes — the cap is `maxRenderedSeats`, not the size of the chart.
1039
+ *
1040
+ * Two ways in, both always present. The map supports pan, pinch-zoom and a
1041
+ * roving keyboard cursor (arrows to move, Home/End for the row ends,
1042
+ * PageUp/PageDown between sections, Enter to toggle). Moving the cursor forces
1043
+ * seat-level detail and pans to follow, because a focused element that gets
1044
+ * culled away takes the focus with it. Alongside it, `showList` opens a plain
1045
+ * section → row → seat picker with a "best available" button — the only
1046
+ * workable path with a screen reader, and the one most sighted buyers want too.
1047
+ *
1048
+ * Accessible seats are distinguished by shape, pattern and text as well as
1049
+ * colour, and survive being sold: use `Seat.accessType`, since `SeatStatus`
1050
+ * alone cannot represent a sold wheelchair space.
1051
+ */
1052
+ export declare const NiceSeatingChart: default_2.ForwardRefExoticComponent<NiceSeatingChartProps & default_2.RefAttributes<HTMLDivElement>>;
1053
+
1054
+ /** Props for {@link NiceSeatingChart}. */
1055
+ export declare interface NiceSeatingChartProps {
1056
+ /** The venue layout, using the existing `SeatingChart` type. */
1057
+ chart: SeatingChart;
1058
+ /** `select` lets a buyer pick seats; `view` is read-only; `design` is reserved. */
1059
+ mode?: 'design' | 'select' | 'view';
1060
+ /** Selection rules: how many, which categories, whether gaps are allowed. */
1061
+ selection?: SeatSelectionConfig;
1062
+ /** Controlled selection. */
1063
+ selectedSeatIds?: string[];
1064
+ defaultSelectedSeatIds?: string[];
1065
+ onSelectionChange?: (seatIds: string[]) => void;
1066
+ /** Fires when a click is refused, with the reason. */
1067
+ onSelectionRejected?: (rejection: {
1068
+ reason: SelectionRejection;
1069
+ seatId: string;
1070
+ }) => void;
1071
+ /** Live availability from the backend, overriding the statuses in `chart`. */
1072
+ seatStatusOverrides?: Record<string, Seat['status']>;
1073
+ onSeatClick?: (seat: Seat) => void;
1074
+ /**
1075
+ * Called when the buyer asks for the best available block. Leave unset to
1076
+ * use the built-in pick (highest average view score in a legal run).
1077
+ */
1078
+ onBestAvailable?: (count: number, options: {
1079
+ sectionId?: string;
1080
+ }) => void;
1081
+ /** Detail level. `auto` picks from how many seats are actually in view. */
1082
+ lod?: 'auto' | SeatLodTier;
1083
+ onLodChange?: (tier: SeatLodTier) => void;
1084
+ /** Cap on seat nodes drawn at once. Default `2500`. */
1085
+ maxRenderedSeats?: number;
1086
+ /** Override the measured size — needed in tests and for SSR. */
1087
+ containerSize?: ContainerSize;
1088
+ showLegend?: boolean;
1089
+ /** Show the non-visual section/row/seat picker. Default `false` here. */
1090
+ showList?: boolean;
1091
+ zoomable?: boolean;
1092
+ locale?: string;
1093
+ disabled?: boolean;
1094
+ readOnly?: boolean;
1095
+ className?: string;
1096
+ style?: default_2.CSSProperties;
1097
+ }
1098
+
1099
+ /**
1100
+ * {@link NiceSeatPicker} — the buy-a-ticket view: pick seats, see the total.
1101
+ *
1102
+ * A preset over {@link NiceSeatingChart} with `mode="select"` and the
1103
+ * non-visual section → row → seat list open by default, since that is the
1104
+ * flow most buyers use on a phone. Not a second implementation — every rule,
1105
+ * from adjacency to accessible-seat rendering, is the same code.
1106
+ *
1107
+ * Reach for {@link NiceSeatingChart} directly when you need `view` mode or
1108
+ * control over the level of detail.
1109
+ */
1110
+ export declare const NiceSeatPicker: default_2.ForwardRefExoticComponent<NiceSeatPickerProps & default_2.RefAttributes<HTMLDivElement>>;
1111
+
1112
+ /**
1113
+ * Props for {@link NiceSeatPicker} — {@link NiceSeatingChartProps} without the
1114
+ * options that only make sense in the full editor.
1115
+ */
1116
+ export declare type NiceSeatPickerProps = Omit<NiceSeatingChartProps, 'mode' | 'lod' | 'onLodChange'>;
1117
+
1118
+ /** One payment in a settlement plan: `fromId` pays `toId`. */
1119
+ export declare interface NiceSettlementTransfer {
1120
+ fromId: string;
1121
+ fromName: string;
1122
+ toId: string;
1123
+ toName: string;
1124
+ /** Major units (e.g. 12.50), matching {@link BillingItem.amount}. */
1125
+ amount: number;
1126
+ currency: string;
1127
+ }
1128
+
494
1129
  /**
495
1130
  * {@link NiceSongPicker} — Song selection for music events.
496
1131
  */
@@ -531,6 +1166,13 @@ export declare interface OccupancyMapConfig {
531
1166
  alertThreshold: number;
532
1167
  }
533
1168
 
1169
+ /** An extra column, so hosts can show dietary needs or plus-ones without a model change. */
1170
+ export declare interface ParticipantExtraField {
1171
+ key: string;
1172
+ label: string;
1173
+ render?: (participant: EventParticipant) => default_2.ReactNode;
1174
+ }
1175
+
534
1176
  /** Participant role. */
535
1177
  export declare type ParticipantRole = 'host' | 'co-host' | 'moderator' | 'participant' | 'spectator' | 'vip';
536
1178
 
@@ -548,6 +1190,16 @@ export declare interface RoundScore {
548
1190
  /** Round status. */
549
1191
  export declare type RoundStatus = 'upcoming' | 'active' | 'voting' | 'scored' | 'completed' | 'skipped';
550
1192
 
1193
+ /** Agenda / schedule item (Schedule tab). */
1194
+ export declare interface ScheduleItem {
1195
+ id: string;
1196
+ title: string;
1197
+ startTime?: string;
1198
+ endTime?: string;
1199
+ location?: string;
1200
+ description?: string;
1201
+ }
1202
+
551
1203
  export declare interface Seat {
552
1204
  id: string;
553
1205
  row: string;
@@ -561,6 +1213,18 @@ export declare interface Seat {
561
1213
  priceCategoryId: string;
562
1214
  /** Status */
563
1215
  status: SeatStatus;
1216
+ /**
1217
+ * Accessibility classification, independent of {@link status}.
1218
+ *
1219
+ * `SeatStatus` folds `'wheelchair'`/`'companion'` into the same union as
1220
+ * `'sold'`/`'reserved'`, so a wheelchair seat loses its accessibility metadata
1221
+ * the moment it is booked. Use this field instead: an accessible seat that is
1222
+ * sold is `{ status: 'sold', accessType: 'wheelchair' }`.
1223
+ *
1224
+ * `status: 'wheelchair' | 'companion'` remains supported as a legacy alias for
1225
+ * `{ status: 'available', accessType: … }`.
1226
+ */
1227
+ accessType?: 'wheelchair' | 'companion';
564
1228
  /** View quality score (0-100) */
565
1229
  viewScore?: number;
566
1230
  }
@@ -599,23 +1263,45 @@ export declare interface SeatingSection {
599
1263
  currency: string;
600
1264
  }
601
1265
 
1266
+ /** How much detail the chart draws. */
1267
+ declare type SeatLodTier = 'section' | 'row' | 'seat';
1268
+
602
1269
  export declare interface SeatSelectionConfig {
603
- /** Max seats per order */
604
- maxSeats: number;
605
- /** Show prices */
606
- showPrices: boolean;
607
- /** Show view preview */
608
- showViewPreview: boolean;
609
- /** Interactive zoom/pan */
610
- interactive: boolean;
611
- /** Highlight available sections */
612
- highlightAvailable: boolean;
613
- /** Allow section-level selection */
614
- sectionSelect: boolean;
1270
+ /** Max seats per order. Default `8`. */
1271
+ maxSeats?: number;
1272
+ /** Show prices. Default `true`. */
1273
+ showPrices?: boolean;
1274
+ /** Show view preview. Default `false`. */
1275
+ showViewPreview?: boolean;
1276
+ /** Interactive zoom/pan. Default `true`. */
1277
+ interactive?: boolean;
1278
+ /** Highlight available sections. Default `true`. */
1279
+ highlightAvailable?: boolean;
1280
+ /** Allow section-level selection. Default `false`. */
1281
+ sectionSelect?: boolean;
1282
+ /**
1283
+ * Forbid selections that strand a single empty seat inside a run of
1284
+ * available seats. Applied per row, never across rows.
1285
+ *
1286
+ * Given the run of consecutive selectable seats containing the selection,
1287
+ * a selection is rejected when it leaves exactly one seat free on either
1288
+ * side. Leaving 0 or 2+ seats is allowed, and a run that was already a
1289
+ * single seat may always be taken — you consume an orphan, you don't
1290
+ * create one.
1291
+ */
1292
+ adjacentOnly?: boolean;
1293
+ /**
1294
+ * Restrict selection to these `Seat.priceCategoryId` values. Unset means
1295
+ * every category is selectable.
1296
+ */
1297
+ allowedCategories?: string[];
615
1298
  }
616
1299
 
617
1300
  export declare type SeatStatus = 'available' | 'reserved' | 'sold' | 'blocked' | 'wheelchair' | 'companion';
618
1301
 
1302
+ /** Why a candidate selection was refused. */
1303
+ declare type SelectionRejection = 'unavailable' | 'category-not-allowed' | 'max-seats' | 'not-adjacent' | 'orphan-seat';
1304
+
619
1305
  /** Song entry. */
620
1306
  export declare interface SongEntry {
621
1307
  id: string;