@tuturuuu/ui 0.4.1 → 0.6.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 (107) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/package.json +41 -34
  3. package/src/components/ui/currency-input.tsx +65 -23
  4. package/src/components/ui/custom/__tests__/sidebar-context.test.tsx +64 -0
  5. package/src/components/ui/custom/__tests__/sidebar-remote-behavior-bridge.test.tsx +109 -0
  6. package/src/components/ui/custom/combobox.test.tsx +141 -0
  7. package/src/components/ui/custom/combobox.tsx +105 -36
  8. package/src/components/ui/custom/settings/task-settings.tsx +126 -0
  9. package/src/components/ui/custom/settings/task-sound-settings.test.tsx +146 -0
  10. package/src/components/ui/custom/sidebar-context.tsx +68 -6
  11. package/src/components/ui/custom/sidebar-remote-behavior-bridge.tsx +21 -2
  12. package/src/components/ui/finance/finance-layout.tsx +2 -4
  13. package/src/components/ui/finance/shared/balance-mode-toggle.tsx +35 -0
  14. package/src/components/ui/finance/shared/finance-layout-controls.tsx +43 -0
  15. package/src/components/ui/finance/shared/quick-actions.tsx +14 -6
  16. package/src/components/ui/finance/shared/use-finance-balance-mode.ts +72 -0
  17. package/src/components/ui/finance/shared/wallet-balance-mode.test.ts +66 -0
  18. package/src/components/ui/finance/shared/wallet-balance-mode.ts +42 -0
  19. package/src/components/ui/finance/transactions/form-types.ts +23 -0
  20. package/src/components/ui/finance/transactions/form.tsx +81 -22
  21. package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +29 -18
  22. package/src/components/ui/finance/transactions/transaction-card.tsx +75 -43
  23. package/src/components/ui/finance/transactions/transfer-merge.test.ts +90 -0
  24. package/src/components/ui/finance/transactions/transfer-merge.ts +52 -0
  25. package/src/components/ui/finance/transactions/wallet-filter.tsx +21 -2
  26. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-adjustment-dialog.tsx +219 -0
  27. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-amount.tsx +32 -0
  28. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-delete-dialog.tsx +50 -0
  29. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-dialog.tsx +138 -0
  30. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-history-dialog.tsx +617 -0
  31. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-panel.tsx +197 -0
  32. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoint-sections.tsx +201 -0
  33. package/src/components/ui/finance/wallets/checkpoints/wallet-checkpoints.test.tsx +541 -0
  34. package/src/components/ui/finance/wallets/checkpoints/wallet-total-check-dialog.tsx +362 -0
  35. package/src/components/ui/finance/wallets/columns-rendering.test.tsx +125 -0
  36. package/src/components/ui/finance/wallets/columns.test.ts +56 -0
  37. package/src/components/ui/finance/wallets/columns.tsx +196 -43
  38. package/src/components/ui/finance/wallets/form.test.tsx +79 -14
  39. package/src/components/ui/finance/wallets/form.tsx +41 -197
  40. package/src/components/ui/finance/wallets/query-invalidation.ts +3 -0
  41. package/src/components/ui/finance/wallets/wallet-basics-fields.tsx +141 -0
  42. package/src/components/ui/finance/wallets/wallet-credit-fields.tsx +136 -0
  43. package/src/components/ui/finance/wallets/walletId/credit-wallet-summary.tsx +143 -68
  44. package/src/components/ui/finance/wallets/walletId/wallet-details-actions.test.tsx +105 -0
  45. package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +120 -16
  46. package/src/components/ui/finance/wallets/walletId/wallet-details-amount.test.tsx +64 -0
  47. package/src/components/ui/finance/wallets/walletId/wallet-details-amount.tsx +226 -6
  48. package/src/components/ui/finance/wallets/walletId/wallet-details-page.test.tsx +71 -5
  49. package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +52 -35
  50. package/src/components/ui/finance/wallets/wallets-data-table.test.tsx +171 -0
  51. package/src/components/ui/finance/wallets/wallets-data-table.tsx +132 -29
  52. package/src/components/ui/finance/wallets/wallets-page.test.tsx +117 -36
  53. package/src/components/ui/finance/wallets/wallets-page.tsx +40 -64
  54. package/src/components/ui/storefront/accent-button.tsx +33 -0
  55. package/src/components/ui/storefront/cart-summary.tsx +140 -0
  56. package/src/components/ui/storefront/empty-listings.tsx +32 -0
  57. package/src/components/ui/storefront/hero-panel.tsx +70 -0
  58. package/src/components/ui/storefront/image-panel.tsx +40 -0
  59. package/src/components/ui/storefront/index.ts +12 -0
  60. package/src/components/ui/storefront/listing-card.tsx +129 -0
  61. package/src/components/ui/storefront/storefront-surface.test.tsx +85 -0
  62. package/src/components/ui/storefront/storefront-surface.tsx +235 -0
  63. package/src/components/ui/storefront/types.ts +99 -0
  64. package/src/components/ui/storefront/utils.ts +90 -0
  65. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/__tests__/bulk-mutations-move.test.tsx +14 -0
  66. package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operations.ts +29 -0
  67. package/src/components/ui/tu-do/boards/boardId/task-card/task-card-open-options.test.ts +134 -0
  68. package/src/components/ui/tu-do/boards/boardId/task-card/task-card-open-options.ts +127 -0
  69. package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +17 -42
  70. package/src/components/ui/tu-do/boards/boardId/timeline-board-open-task.test.tsx +164 -0
  71. package/src/components/ui/tu-do/boards/boardId/timeline-board.tsx +25 -16
  72. package/src/components/ui/tu-do/hooks/useTaskDialog.ts +15 -1
  73. package/src/components/ui/tu-do/my-tasks/__tests__/use-task-context-actions.test.ts +11 -0
  74. package/src/components/ui/tu-do/my-tasks/use-my-tasks-state.ts +2 -0
  75. package/src/components/ui/tu-do/my-tasks/use-task-context-actions.ts +124 -7
  76. package/src/components/ui/tu-do/providers/__tests__/task-dialog-provider.test.tsx +217 -5
  77. package/src/components/ui/tu-do/providers/task-dialog-provider.tsx +180 -35
  78. package/src/components/ui/tu-do/shared/__tests__/task-dialog-manager.test.tsx +222 -26
  79. package/src/components/ui/tu-do/shared/board-client.tsx +1 -3
  80. package/src/components/ui/tu-do/shared/list-view-context-menu.test.tsx +55 -2
  81. package/src/components/ui/tu-do/shared/list-view.tsx +23 -16
  82. package/src/components/ui/tu-do/shared/task-dialog-manager.tsx +93 -76
  83. package/src/components/ui/tu-do/shared/task-dialog-presentation.ts +11 -0
  84. package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.test.tsx +268 -0
  85. package/src/components/ui/tu-do/shared/task-edit-dialog/components/compact-task-create-popover.tsx +243 -0
  86. package/src/components/ui/tu-do/shared/task-edit-dialog/components/quick-settings-popover.tsx +26 -0
  87. package/src/components/ui/tu-do/shared/task-edit-dialog/components/smart-task-suggestions-panel.test.tsx +129 -0
  88. package/src/components/ui/tu-do/shared/task-edit-dialog/components/smart-task-suggestions-panel.tsx +358 -0
  89. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-description-editor.tsx +1 -1
  90. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-dialog-header.tsx +6 -2
  91. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-list-selector.tsx +36 -20
  92. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-name-input.test.tsx +41 -1
  93. package/src/components/ui/tu-do/shared/task-edit-dialog/components/task-name-input.tsx +157 -102
  94. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-form-reset.ts +18 -2
  95. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-realtime-sync.ts +1 -2
  96. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-save.test.ts +84 -1
  97. package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-save.ts +5 -1
  98. package/src/components/ui/tu-do/shared/task-edit-dialog/task-dialog-actions.tsx +5 -3
  99. package/src/components/ui/tu-do/shared/task-edit-dialog/task-properties-section.tsx +300 -172
  100. package/src/components/ui/tu-do/shared/task-edit-dialog.tsx +959 -340
  101. package/src/components/ui/tu-do/shared/task-sound-effects.test.ts +189 -0
  102. package/src/components/ui/tu-do/shared/task-sound-effects.tsx +468 -0
  103. package/src/hooks/__tests__/use-task-actions.test.tsx +61 -0
  104. package/src/hooks/use-task-actions.ts +45 -0
  105. package/src/hooks/useBoardRealtime.ts +54 -1
  106. package/src/hooks/useBoardRealtimeEventHandler.ts +169 -4
  107. package/src/hooks/useTaskUserRealtime.ts +338 -0
@@ -0,0 +1,138 @@
1
+ 'use client';
2
+
3
+ import type { WalletCheckpoint } from '@tuturuuu/internal-api/finance';
4
+ import { Button } from '@tuturuuu/ui/button';
5
+ import {
6
+ Dialog,
7
+ DialogContent,
8
+ DialogDescription,
9
+ DialogFooter,
10
+ DialogHeader,
11
+ DialogTitle,
12
+ } from '@tuturuuu/ui/dialog';
13
+ import { Input } from '@tuturuuu/ui/input';
14
+ import { Label } from '@tuturuuu/ui/label';
15
+ import { Textarea } from '@tuturuuu/ui/textarea';
16
+ import { useTranslations } from 'next-intl';
17
+ import { useEffect, useMemo, useState } from 'react';
18
+
19
+ function toLocalInputValue(value?: string) {
20
+ const date = value ? new Date(value) : new Date();
21
+ const local = new Date(date.getTime() - date.getTimezoneOffset() * 60_000);
22
+ return local.toISOString().slice(0, 16);
23
+ }
24
+
25
+ function toIsoTimestamp(value: string) {
26
+ const date = new Date(value);
27
+ return Number.isFinite(date.getTime()) ? date.toISOString() : null;
28
+ }
29
+
30
+ export function WalletCheckpointDialog({
31
+ checkpoint,
32
+ currency,
33
+ isPending,
34
+ mode,
35
+ onOpenChange,
36
+ onSubmit,
37
+ open,
38
+ }: {
39
+ checkpoint?: WalletCheckpoint | null;
40
+ currency: string;
41
+ isPending: boolean;
42
+ mode: 'create' | 'edit';
43
+ onOpenChange: (open: boolean) => void;
44
+ onSubmit: (payload: {
45
+ actual_balance: number;
46
+ checked_at: string;
47
+ note: string | null;
48
+ }) => void;
49
+ open: boolean;
50
+ }) {
51
+ const t = useTranslations('wallet-checkpoints');
52
+ const [amount, setAmount] = useState('');
53
+ const [checkedAt, setCheckedAt] = useState(toLocalInputValue());
54
+ const [note, setNote] = useState('');
55
+
56
+ useEffect(() => {
57
+ if (!open) return;
58
+ setAmount(checkpoint ? String(checkpoint.actual_balance) : '');
59
+ setCheckedAt(toLocalInputValue(checkpoint?.checked_at));
60
+ setNote(checkpoint?.note ?? '');
61
+ }, [checkpoint, open]);
62
+
63
+ const parsedAmount = useMemo(() => Number(amount), [amount]);
64
+ const isoTimestamp = useMemo(() => toIsoTimestamp(checkedAt), [checkedAt]);
65
+ const canSubmit = Number.isFinite(parsedAmount) && !!isoTimestamp;
66
+
67
+ return (
68
+ <Dialog open={open} onOpenChange={onOpenChange}>
69
+ <DialogContent>
70
+ <DialogHeader>
71
+ <DialogTitle>
72
+ {mode === 'edit' ? t('edit_checkpoint') : t('record_checkpoint')}
73
+ </DialogTitle>
74
+ <DialogDescription>
75
+ {mode === 'edit'
76
+ ? t('edit_checkpoint_description')
77
+ : t('record_checkpoint_description')}
78
+ </DialogDescription>
79
+ </DialogHeader>
80
+ <div className="grid gap-4 py-2">
81
+ <div className="grid gap-2">
82
+ <Label htmlFor="checkpoint-amount">
83
+ {t('actual_balance_with_currency', { currency })}
84
+ </Label>
85
+ <Input
86
+ id="checkpoint-amount"
87
+ inputMode="decimal"
88
+ value={amount}
89
+ onChange={(event) => setAmount(event.target.value)}
90
+ placeholder="0"
91
+ />
92
+ </div>
93
+ <div className="grid gap-2">
94
+ <Label htmlFor="checkpoint-checked-at">{t('checked_at')}</Label>
95
+ <Input
96
+ id="checkpoint-checked-at"
97
+ type="datetime-local"
98
+ value={checkedAt}
99
+ onChange={(event) => setCheckedAt(event.target.value)}
100
+ />
101
+ </div>
102
+ <div className="grid gap-2">
103
+ <Label htmlFor="checkpoint-note">{t('note')}</Label>
104
+ <Textarea
105
+ id="checkpoint-note"
106
+ value={note}
107
+ maxLength={500}
108
+ onChange={(event) => setNote(event.target.value)}
109
+ />
110
+ </div>
111
+ </div>
112
+ <DialogFooter>
113
+ <Button
114
+ type="button"
115
+ variant="outline"
116
+ onClick={() => onOpenChange(false)}
117
+ >
118
+ {t('cancel')}
119
+ </Button>
120
+ <Button
121
+ type="button"
122
+ disabled={!canSubmit || isPending}
123
+ onClick={() => {
124
+ if (!isoTimestamp) return;
125
+ onSubmit({
126
+ actual_balance: parsedAmount,
127
+ checked_at: isoTimestamp,
128
+ note: note.trim() || null,
129
+ });
130
+ }}
131
+ >
132
+ {isPending ? t('saving') : t('save_checkpoint')}
133
+ </Button>
134
+ </DialogFooter>
135
+ </DialogContent>
136
+ </Dialog>
137
+ );
138
+ }