@tuturuuu/ui 0.6.2 → 0.8.0

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 (108) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/biome.json +1 -1
  3. package/package.json +11 -11
  4. package/src/components/ui/calendar-app/components/calendar-connections.tsx +17 -13
  5. package/src/components/ui/calendar-app/components/connected-accounts-dialog.tsx +2 -5
  6. package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +2 -5
  7. package/src/components/ui/calendar.test.tsx +24 -0
  8. package/src/components/ui/calendar.tsx +1 -0
  9. package/src/components/ui/currency-input.test.tsx +43 -0
  10. package/src/components/ui/currency-input.tsx +1 -1
  11. package/src/components/ui/custom/workspace-access/workspace-access-default-role-card.tsx +60 -35
  12. package/src/components/ui/custom/workspace-access/workspace-access-member-row.tsx +176 -167
  13. package/src/components/ui/custom/workspace-access/workspace-access-members.tsx +16 -10
  14. package/src/components/ui/custom/workspace-access/workspace-access-page-header.tsx +75 -36
  15. package/src/components/ui/custom/workspace-access/workspace-access-page.tsx +39 -42
  16. package/src/components/ui/custom/workspace-access/workspace-access-people-filters.tsx +1 -1
  17. package/src/components/ui/custom/workspace-access/workspace-access-roles.tsx +113 -91
  18. package/src/components/ui/custom/workspace-access/workspace-access-tabs-toolbar.tsx +73 -32
  19. package/src/components/ui/date-time-picker.tsx +352 -234
  20. package/src/components/ui/finance/categories-tags-tabs.tsx +23 -1
  21. package/src/components/ui/finance/command/finance-command-actions.test.tsx +48 -0
  22. package/src/components/ui/finance/command/finance-command-actions.tsx +200 -0
  23. package/src/components/ui/finance/command/finance-command-provider.test.tsx +151 -0
  24. package/src/components/ui/finance/command/finance-command-provider.tsx +250 -0
  25. package/src/components/ui/finance/command/finance-command-results.tsx +262 -0
  26. package/src/components/ui/finance/invoices/pending-invoices-table.tsx +22 -9
  27. package/src/components/ui/finance/shared/quick-actions.tsx +39 -90
  28. package/src/components/ui/finance/tags/tag-manager.tsx +24 -5
  29. package/src/components/ui/finance/transactions/form-basic-tab.tsx +33 -49
  30. package/src/components/ui/finance/transactions/form-types.ts +5 -0
  31. package/src/components/ui/finance/transactions/form.test.tsx +105 -22
  32. package/src/components/ui/finance/transactions/form.tsx +116 -20
  33. package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +13 -6
  34. package/src/components/ui/finance/transactions/transaction-card.tsx +21 -9
  35. package/src/components/ui/finance/transactions/transaction-edit-dialog.test.tsx +25 -1
  36. package/src/components/ui/finance/transactions/transaction-edit-dialog.tsx +16 -3
  37. package/src/components/ui/finance/transactions/transactionId/transaction-details-client-page.tsx +3 -0
  38. package/src/components/ui/finance/transactions/transactionId/transaction-details-page.tsx +3 -0
  39. package/src/components/ui/finance/transactions/transactions-create-summary.tsx +6 -0
  40. package/src/components/ui/finance/transactions/transactions-infinite-page.tsx +20 -2
  41. package/src/components/ui/finance/transactions/transactions-page.tsx +4 -0
  42. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-history-dialog.tsx +7 -2
  43. package/src/components/ui/finance/wallets/checkpoints/wallet-total-check-dialog.tsx +7 -2
  44. package/src/components/ui/finance/wallets/walletId/wallet-details-actions.test.tsx +38 -1
  45. package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +5 -0
  46. package/src/components/ui/finance/wallets/walletId/wallet-details-page.test.tsx +18 -2
  47. package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +3 -0
  48. package/src/components/ui/finance/wallets/wallets-page.tsx +3 -0
  49. package/src/components/ui/legacy/calendar/settings/google-calendar-settings.tsx +2 -9
  50. package/src/components/ui/money-input.test.tsx +64 -0
  51. package/src/components/ui/money-input.tsx +63 -0
  52. package/src/components/ui/optional-time-picker.tsx +95 -0
  53. package/src/components/ui/quick-command-center.test.tsx +90 -0
  54. package/src/components/ui/quick-command-center.tsx +190 -0
  55. package/src/components/ui/storefront/cart-summary.tsx +126 -50
  56. package/src/components/ui/storefront/checkout-overlay.tsx +27 -0
  57. package/src/components/ui/storefront/hero-panel.tsx +23 -20
  58. package/src/components/ui/storefront/image-panel.tsx +6 -0
  59. package/src/components/ui/storefront/index.ts +11 -0
  60. package/src/components/ui/storefront/listing-card.tsx +84 -22
  61. package/src/components/ui/storefront/product-detail.tsx +289 -0
  62. package/src/components/ui/storefront/product-dialog.tsx +72 -0
  63. package/src/components/ui/storefront/storefront-surface.test.tsx +132 -5
  64. package/src/components/ui/storefront/storefront-surface.tsx +371 -128
  65. package/src/components/ui/storefront/types.ts +25 -1
  66. package/src/components/ui/storefront/utils.ts +118 -13
  67. package/src/components/ui/text-editor/__tests__/content-migration.test.ts +32 -0
  68. package/src/components/ui/text-editor/__tests__/image-extension.test.ts +69 -1
  69. package/src/components/ui/text-editor/__tests__/video-extension.test.ts +47 -0
  70. package/src/components/ui/text-editor/content-migration.ts +41 -18
  71. package/src/components/ui/text-editor/extensions.ts +1 -1
  72. package/src/components/ui/text-editor/image-extension.ts +40 -18
  73. package/src/components/ui/text-editor/video-extension.ts +11 -2
  74. package/src/components/ui/tu-do/boards/__tests__/workspace-projects-client-page.test.tsx +70 -1
  75. package/src/components/ui/tu-do/boards/boardId/board-column-external-retry.test.tsx +127 -0
  76. package/src/components/ui/tu-do/boards/boardId/board-column.tsx +1 -3
  77. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/task-drag-cache.ts +13 -0
  78. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.test.ts +63 -0
  79. package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +46 -8
  80. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +13 -2
  81. package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +3 -1
  82. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.test.tsx +164 -0
  83. package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +56 -2
  84. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-display.ts +9 -0
  85. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-grid.tsx +8 -16
  86. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-task-row.tsx +5 -25
  87. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-utils.test.ts +36 -1
  88. package/src/components/ui/tu-do/boards/boardId/timeline/timeline-utils.ts +51 -2
  89. package/src/components/ui/tu-do/boards/workspace-projects-client-page.tsx +13 -3
  90. package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +34 -1
  91. package/src/components/ui/tu-do/shared/board-header.tsx +39 -0
  92. package/src/components/ui/tu-do/shared/board-views.tsx +9 -7
  93. package/src/components/ui/tu-do/shared/cursor-overlay-multi-wrapper.tsx +53 -12
  94. package/src/components/ui/tu-do/shared/task-dialog-presentation.test.ts +53 -0
  95. package/src/components/ui/tu-do/shared/task-dialog-presentation.ts +19 -0
  96. package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.test.tsx +57 -0
  97. package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.tsx +136 -111
  98. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-description-editor.tsx +3 -1
  99. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/task-api.test.ts +171 -0
  100. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/task-api.ts +200 -36
  101. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-save.ts +21 -2
  102. package/src/components/ui/tu-do/shared/task-edit-dialog.tsx +42 -14
  103. package/src/hooks/__tests__/useBoardRealtime.test.tsx +2 -2
  104. package/src/hooks/__tests__/useCursorTracking.test.tsx +212 -0
  105. package/src/hooks/useBoardRealtime.ts +6 -3
  106. package/src/hooks/useBoardRealtime.types.ts +11 -0
  107. package/src/hooks/useCursorTracking.ts +91 -27
  108. package/src/hooks/useTaskUserRealtime.ts +5 -3
@@ -1,12 +1,17 @@
1
1
  import { render, screen } from '@testing-library/react';
2
- import type { InventoryStorefront } from '@tuturuuu/internal-api/inventory';
2
+ import type {
3
+ InventoryStorefront,
4
+ InventoryStorefrontListing,
5
+ } from '@tuturuuu/internal-api/inventory';
3
6
  import { describe, expect, it } from 'vitest';
4
7
  import { StorefrontSurface } from './storefront-surface';
5
8
  import { sanitizeStorefrontAccentColor } from './utils';
6
9
 
7
10
  const storefront: InventoryStorefront = {
8
11
  accentColor: '#abc',
12
+ analyticsEnabled: true,
9
13
  cornerStyle: 'rounded',
14
+ coverImageUrl: null,
10
15
  createdAt: '2026-06-12T00:00:00.000Z',
11
16
  currency: 'USD',
12
17
  checkoutMode: 'polar',
@@ -16,6 +21,7 @@ const storefront: InventoryStorefront = {
16
21
  layoutStyle: 'grid',
17
22
  listingsCount: 0,
18
23
  name: 'Preview Store',
24
+ sections: [],
19
25
  showInventoryBadges: true,
20
26
  slug: 'preview-store',
21
27
  status: 'published',
@@ -26,6 +32,30 @@ const storefront: InventoryStorefront = {
26
32
  wsId: 'ws-1',
27
33
  };
28
34
 
35
+ const listing: InventoryStorefrontListing = {
36
+ availableQuantity: 8,
37
+ bundleId: null,
38
+ compareAtPrice: null,
39
+ createdAt: '2026-06-12T00:00:00.000Z',
40
+ description: 'A mentoring session for checkout tests.',
41
+ id: 'listing-1',
42
+ imageUrl: null,
43
+ listingType: 'product',
44
+ maxPerOrder: 5,
45
+ price: 100,
46
+ productId: 'product-1',
47
+ sortOrder: 1,
48
+ status: 'published',
49
+ storefrontId: storefront.id,
50
+ title: '1:1 Mentoring',
51
+ unitId: 'unit-1',
52
+ unitName: 'Session',
53
+ updatedAt: '2026-06-12T00:00:00.000Z',
54
+ warehouseId: 'warehouse-1',
55
+ warehouseName: 'Main',
56
+ wsId: storefront.wsId,
57
+ };
58
+
29
59
  describe('StorefrontSurface', () => {
30
60
  it('sanitizes hex accent colors only', () => {
31
61
  expect(sanitizeStorefrontAccentColor('#abc')).toBe('#aabbcc');
@@ -53,7 +83,51 @@ describe('StorefrontSurface', () => {
53
83
  expect(screen.getByText('Preview checkout disabled')).toBeDisabled();
54
84
  });
55
85
 
56
- it('shows simulated checkout mode badges', () => {
86
+ it('links storefront chrome back to the store and keeps the cart icon stable', () => {
87
+ render(
88
+ <StorefrontSurface
89
+ cartHref="/preview-store/cart"
90
+ cartLines={[{ listingId: listing.id, quantity: 2 }]}
91
+ listings={[listing]}
92
+ mode="store"
93
+ storefront={storefront}
94
+ storefrontHref="/preview-store"
95
+ />
96
+ );
97
+
98
+ expect(screen.getByRole('link', { name: 'Preview Store' })).toHaveAttribute(
99
+ 'href',
100
+ '/preview-store'
101
+ );
102
+
103
+ const cartLink = screen.getByRole('link', { name: 'Cart: 2' });
104
+ expect(cartLink).toHaveAttribute('href', '/preview-store/cart');
105
+ expect(cartLink).toHaveClass('h-11', 'min-w-14', 'shrink-0');
106
+ expect(cartLink.querySelector('svg')).toHaveClass('size-5', 'shrink-0');
107
+ });
108
+
109
+ it('prefills checkout buyer details while keeping editable form fields', () => {
110
+ render(
111
+ <StorefrontSurface
112
+ buyerDefaults={{
113
+ email: 'buyer@example.com',
114
+ name: 'Sokora Buyer',
115
+ }}
116
+ cartLines={[{ listingId: listing.id, quantity: 1 }]}
117
+ listings={[listing]}
118
+ mode="checkout"
119
+ onCheckoutSubmit={() => undefined}
120
+ storefront={storefront}
121
+ />
122
+ );
123
+
124
+ expect(screen.getByLabelText('Name')).toHaveValue('Sokora Buyer');
125
+ expect(screen.getByLabelText('Email')).toHaveValue('buyer@example.com');
126
+ expect(screen.getByLabelText('Name')).toBeEnabled();
127
+ expect(screen.getByLabelText('Email')).toBeEnabled();
128
+ });
129
+
130
+ it('keeps simulated storefront chrome customer-facing', () => {
57
131
  render(
58
132
  <StorefrontSurface
59
133
  labels={{ simulatedBadge: 'Simulated checkout' }}
@@ -63,10 +137,11 @@ describe('StorefrontSurface', () => {
63
137
  />
64
138
  );
65
139
 
66
- expect(screen.getByText('Simulated checkout')).toBeInTheDocument();
140
+ expect(screen.queryByText('Simulated checkout')).not.toBeInTheDocument();
141
+ expect(screen.getAllByText('Preview Store')).toHaveLength(2);
67
142
  });
68
143
 
69
- it('shows disabled checkout mode badges and blocks checkout', () => {
144
+ it('blocks disabled checkout without showing checkout mode badges', () => {
70
145
  render(
71
146
  <StorefrontSurface
72
147
  labels={{
@@ -79,7 +154,59 @@ describe('StorefrontSurface', () => {
79
154
  />
80
155
  );
81
156
 
82
- expect(screen.getByText('Checkout disabled')).toBeInTheDocument();
157
+ expect(screen.queryByText('Checkout disabled')).not.toBeInTheDocument();
83
158
  expect(screen.getByText('Checkout unavailable')).toBeDisabled();
84
159
  });
160
+
161
+ it('renders only http storefront section links', () => {
162
+ render(
163
+ <StorefrontSurface
164
+ listings={[]}
165
+ mode="store"
166
+ storefront={{
167
+ ...storefront,
168
+ sections: [
169
+ {
170
+ createdAt: null,
171
+ description: null,
172
+ href: 'javascript:alert(document.domain)',
173
+ id: 'section-unsafe',
174
+ imageUrl: null,
175
+ items: [],
176
+ metadata: {},
177
+ sectionType: 'promo',
178
+ sortOrder: 0,
179
+ status: 'published',
180
+ storefrontId: storefront.id,
181
+ title: 'Unsafe section',
182
+ updatedAt: null,
183
+ wsId: storefront.wsId,
184
+ },
185
+ {
186
+ createdAt: null,
187
+ description: null,
188
+ href: 'https://example.com/promo',
189
+ id: 'section-safe',
190
+ imageUrl: null,
191
+ items: [],
192
+ metadata: {},
193
+ sectionType: 'promo',
194
+ sortOrder: 1,
195
+ status: 'published',
196
+ storefrontId: storefront.id,
197
+ title: 'Safe section',
198
+ updatedAt: null,
199
+ wsId: storefront.wsId,
200
+ },
201
+ ],
202
+ }}
203
+ />
204
+ );
205
+
206
+ expect(screen.getByText('Safe section')).toBeInTheDocument();
207
+ expect(
208
+ screen.getByRole('link', { name: 'example.com/promo' })
209
+ ).toHaveAttribute('href', 'https://example.com/promo');
210
+ expect(screen.queryByText('javascript:alert(document.domain)')).toBeNull();
211
+ });
85
212
  });