@hed-hog/tag 0.0.304 → 0.0.306
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/hedhog/frontend/app/page.tsx.ejs +114 -16
- package/package.json +4 -4
|
@@ -47,12 +47,16 @@ import {
|
|
|
47
47
|
SheetTitle,
|
|
48
48
|
} from '@/components/ui/sheet';
|
|
49
49
|
import { useDebounce } from '@/hooks/use-debounce';
|
|
50
|
+
import { useFormDraft } from '@/hooks/use-form-draft';
|
|
51
|
+
import { formatDateTime } from '@/lib/format-date';
|
|
50
52
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
51
53
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
54
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
55
|
+
import { enUS, ptBR } from 'date-fns/locale';
|
|
52
56
|
import { Edit, Save, Tag as TagIcon, Trash2 } from 'lucide-react';
|
|
53
57
|
import { useTranslations } from 'next-intl';
|
|
54
58
|
import { useEffect, useMemo, useState } from 'react';
|
|
55
|
-
import { useForm } from 'react-hook-form';
|
|
59
|
+
import { useForm, useWatch } from 'react-hook-form';
|
|
56
60
|
import { toast } from 'sonner';
|
|
57
61
|
import { z } from 'zod';
|
|
58
62
|
|
|
@@ -70,6 +74,23 @@ type Tag = {
|
|
|
70
74
|
status: 'active' | 'inactive';
|
|
71
75
|
};
|
|
72
76
|
|
|
77
|
+
type TagStats = {
|
|
78
|
+
total: number;
|
|
79
|
+
active: number;
|
|
80
|
+
inactive: number;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
type TagDraftPayload = {
|
|
84
|
+
mode: 'create' | 'edit';
|
|
85
|
+
tagId: number | null;
|
|
86
|
+
values: {
|
|
87
|
+
slug: string;
|
|
88
|
+
color: string;
|
|
89
|
+
status: 'active' | 'inactive';
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const TAG_FORM_DRAFT_STORAGE_KEY = 'tag-form-draft';
|
|
73
94
|
const PAGE_SIZE_OPTIONS: number[] = [10, 20, 30, 40, 50];
|
|
74
95
|
|
|
75
96
|
export default function TagPage() {
|
|
@@ -94,7 +115,7 @@ export default function TagPage() {
|
|
|
94
115
|
const debouncedSearch = useDebounce(searchTerm);
|
|
95
116
|
const [page, setPage] = useState(1);
|
|
96
117
|
const [pageSize, setPageSize] = useState<number>(10);
|
|
97
|
-
const { request } = useApp();
|
|
118
|
+
const { request, currentLocaleCode, getSettingValue } = useApp();
|
|
98
119
|
|
|
99
120
|
const form = useForm<FormValues>({
|
|
100
121
|
resolver: zodResolver(formSchema),
|
|
@@ -105,6 +126,62 @@ export default function TagPage() {
|
|
|
105
126
|
},
|
|
106
127
|
});
|
|
107
128
|
|
|
129
|
+
const watchedTagValues = useWatch({
|
|
130
|
+
control: form.control,
|
|
131
|
+
});
|
|
132
|
+
const hasDraftContent = Boolean(
|
|
133
|
+
(watchedTagValues.slug ?? '').trim() ||
|
|
134
|
+
watchedTagValues.color !== '#000000' ||
|
|
135
|
+
watchedTagValues.status !== 'active'
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const {
|
|
139
|
+
clearDraft,
|
|
140
|
+
loadDraft,
|
|
141
|
+
hasDraft,
|
|
142
|
+
savedAt: draftSavedAt,
|
|
143
|
+
} = useFormDraft<TagDraftPayload>({
|
|
144
|
+
storageKey: TAG_FORM_DRAFT_STORAGE_KEY,
|
|
145
|
+
value: {
|
|
146
|
+
mode: editingTagId ? 'edit' : 'create',
|
|
147
|
+
tagId: editingTagId,
|
|
148
|
+
values: {
|
|
149
|
+
slug: watchedTagValues.slug ?? '',
|
|
150
|
+
color: watchedTagValues.color ?? '#000000',
|
|
151
|
+
status: watchedTagValues.status ?? 'active',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
hasData: hasDraftContent,
|
|
155
|
+
enabled: isSheetOpen,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const draftStatusContent = useMemo(() => {
|
|
159
|
+
if (!hasDraft || !draftSavedAt) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const savedDate = new Date(draftSavedAt);
|
|
164
|
+
|
|
165
|
+
if (Number.isNaN(savedDate.getTime())) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
|
|
170
|
+
const relativeLabel = formatDistanceToNow(savedDate, {
|
|
171
|
+
addSuffix: true,
|
|
172
|
+
locale,
|
|
173
|
+
});
|
|
174
|
+
const absoluteLabel = formatDateTime(
|
|
175
|
+
savedDate,
|
|
176
|
+
getSettingValue,
|
|
177
|
+
currentLocaleCode
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return currentLocaleCode.startsWith('pt')
|
|
181
|
+
? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
|
|
182
|
+
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
183
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
184
|
+
|
|
108
185
|
const { data: tagResult, refetch: refetchTag } = useQuery<
|
|
109
186
|
PaginationResult<Tag>
|
|
110
187
|
>({
|
|
@@ -123,22 +200,28 @@ export default function TagPage() {
|
|
|
123
200
|
});
|
|
124
201
|
const { data = [], total = 0 } = tagResult ?? {};
|
|
125
202
|
|
|
126
|
-
const { data: statsData, refetch: refetchStats } = useQuery<
|
|
203
|
+
const { data: statsData, refetch: refetchStats } = useQuery<TagStats>({
|
|
127
204
|
queryKey: ['tag-stats'],
|
|
128
205
|
queryFn: async () => {
|
|
129
|
-
const response = await request({
|
|
206
|
+
const response = await request<TagStats>({
|
|
130
207
|
url: '/tag/stats',
|
|
131
208
|
});
|
|
132
|
-
return response.data;
|
|
209
|
+
return response.data as TagStats;
|
|
133
210
|
},
|
|
134
211
|
});
|
|
135
212
|
|
|
136
213
|
const handleNewTag = (): void => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
214
|
+
const storedDraft = loadDraft();
|
|
215
|
+
|
|
216
|
+
form.reset(
|
|
217
|
+
storedDraft?.payload.mode === 'create'
|
|
218
|
+
? storedDraft.payload.values
|
|
219
|
+
: {
|
|
220
|
+
slug: '',
|
|
221
|
+
color: '#000000',
|
|
222
|
+
status: 'active',
|
|
223
|
+
}
|
|
224
|
+
);
|
|
142
225
|
setEditingTagId(null);
|
|
143
226
|
setIsSheetOpen(true);
|
|
144
227
|
};
|
|
@@ -150,11 +233,20 @@ export default function TagPage() {
|
|
|
150
233
|
method: 'GET',
|
|
151
234
|
});
|
|
152
235
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
236
|
+
const storedDraft = loadDraft();
|
|
237
|
+
const shouldRestoreDraft =
|
|
238
|
+
storedDraft?.payload.mode === 'edit' &&
|
|
239
|
+
storedDraft.payload.tagId === tag.id;
|
|
240
|
+
|
|
241
|
+
form.reset(
|
|
242
|
+
shouldRestoreDraft
|
|
243
|
+
? storedDraft.payload.values
|
|
244
|
+
: {
|
|
245
|
+
slug: response.data.slug ?? '',
|
|
246
|
+
color: response.data.color ?? '#000000',
|
|
247
|
+
status: response.data.status ?? 'active',
|
|
248
|
+
}
|
|
249
|
+
);
|
|
158
250
|
setEditingTagId(tag.id);
|
|
159
251
|
setIsSheetOpen(true);
|
|
160
252
|
} catch (error) {
|
|
@@ -187,7 +279,9 @@ export default function TagPage() {
|
|
|
187
279
|
toast.success(t('successCreate'));
|
|
188
280
|
}
|
|
189
281
|
|
|
282
|
+
clearDraft();
|
|
190
283
|
setIsSheetOpen(false);
|
|
284
|
+
setEditingTagId(null);
|
|
191
285
|
await refetchTag();
|
|
192
286
|
await refetchStats();
|
|
193
287
|
} catch (error) {
|
|
@@ -456,8 +550,12 @@ export default function TagPage() {
|
|
|
456
550
|
|
|
457
551
|
<FormActions
|
|
458
552
|
sheet
|
|
553
|
+
statusContent={draftStatusContent}
|
|
459
554
|
cancelLabel={t('cancel')}
|
|
460
|
-
onCancel={() =>
|
|
555
|
+
onCancel={() => {
|
|
556
|
+
setIsSheetOpen(false);
|
|
557
|
+
setEditingTagId(null);
|
|
558
|
+
}}
|
|
461
559
|
submitIcon={<Save className="size-4" />}
|
|
462
560
|
submitLabel={t('save')}
|
|
463
561
|
submitType="submit"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/tag",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.306",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
+
"@hed-hog/api": "0.0.6",
|
|
12
13
|
"@hed-hog/api-pagination": "0.0.7",
|
|
14
|
+
"@hed-hog/core": "0.0.306",
|
|
13
15
|
"@hed-hog/api-prisma": "0.0.6",
|
|
14
|
-
"@hed-hog/api": "0.0.
|
|
15
|
-
"@hed-hog/api-locale": "0.0.14",
|
|
16
|
-
"@hed-hog/core": "0.0.304"
|
|
16
|
+
"@hed-hog/api-locale": "0.0.14"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|