@hed-hog/lms 0.0.309 → 0.0.310
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/certificates/models/CanvasStage.tsx.ejs +10 -1
- package/hedhog/frontend/app/certificates/models/TopBar.tsx.ejs +44 -3
- package/hedhog/frontend/app/certificates/models/page.tsx.ejs +32 -0
- package/hedhog/frontend/messages/en.json +3 -1
- package/hedhog/frontend/messages/pt.json +3 -1
- package/package.json +7 -7
|
@@ -658,7 +658,16 @@ async function applyBg(canvas: any, fabricMod: any, src: string) {
|
|
|
658
658
|
});
|
|
659
659
|
const scaleX = CANVAS_W / (img.width || 1);
|
|
660
660
|
const scaleY = CANVAS_H / (img.height || 1);
|
|
661
|
-
img.set({
|
|
661
|
+
img.set({
|
|
662
|
+
left: 0,
|
|
663
|
+
top: 0,
|
|
664
|
+
originX: 'left',
|
|
665
|
+
originY: 'top',
|
|
666
|
+
scaleX,
|
|
667
|
+
scaleY,
|
|
668
|
+
selectable: false,
|
|
669
|
+
evented: false,
|
|
670
|
+
});
|
|
662
671
|
canvas.backgroundImage = img;
|
|
663
672
|
canvas.requestRenderAll();
|
|
664
673
|
} catch {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
ZoomIn,
|
|
22
22
|
ZoomOut,
|
|
23
23
|
} from 'lucide-react';
|
|
24
|
-
import { useCallback, useRef } from 'react';
|
|
24
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
25
25
|
import { toast } from 'sonner';
|
|
26
26
|
import { getCanvasAPI } from '../../_lib/editor/canvasInstance';
|
|
27
27
|
import {
|
|
@@ -63,6 +63,49 @@ export default function Topbar({ templateContext }: TopbarProps) {
|
|
|
63
63
|
|
|
64
64
|
const importRef = useRef<HTMLInputElement>(null);
|
|
65
65
|
|
|
66
|
+
const isFirstRender = useRef(true);
|
|
67
|
+
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
68
|
+
const templateContextRef = useRef(templateContext);
|
|
69
|
+
templateContextRef.current = templateContext;
|
|
70
|
+
const requestRef = useRef(request);
|
|
71
|
+
requestRef.current = request;
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (isFirstRender.current) {
|
|
75
|
+
isFirstRender.current = false;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
localStorage.setItem(LS_KEY, JSON.stringify(templateState));
|
|
80
|
+
|
|
81
|
+
const ctx = templateContextRef.current;
|
|
82
|
+
if (!ctx) return;
|
|
83
|
+
|
|
84
|
+
if (autoSaveTimerRef.current) clearTimeout(autoSaveTimerRef.current);
|
|
85
|
+
|
|
86
|
+
autoSaveTimerRef.current = setTimeout(() => {
|
|
87
|
+
requestRef
|
|
88
|
+
.current({
|
|
89
|
+
url: `/lms/certificates/templates/${ctx.id}`,
|
|
90
|
+
method: 'PATCH',
|
|
91
|
+
data: {
|
|
92
|
+
name: templateState.name,
|
|
93
|
+
slug: ctx.slug,
|
|
94
|
+
status: ctx.status,
|
|
95
|
+
templateContent: JSON.stringify(templateState),
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
.catch(() => {
|
|
99
|
+
toast.error('Falha ao salvar automaticamente');
|
|
100
|
+
});
|
|
101
|
+
}, 1500);
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
if (autoSaveTimerRef.current) clearTimeout(autoSaveTimerRef.current);
|
|
105
|
+
};
|
|
106
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
107
|
+
}, [templateState]);
|
|
108
|
+
|
|
66
109
|
const handleNew = useCallback(() => {
|
|
67
110
|
resetTemplate();
|
|
68
111
|
getCanvasAPI()?.loadTemplate(useTemplateStore.getState().template);
|
|
@@ -72,7 +115,6 @@ export default function Topbar({ templateContext }: TopbarProps) {
|
|
|
72
115
|
const handleSave = useCallback(() => {
|
|
73
116
|
const run = async () => {
|
|
74
117
|
if (!templateContext) {
|
|
75
|
-
localStorage.setItem(LS_KEY, JSON.stringify(templateState));
|
|
76
118
|
toast.success('Template salvo no localStorage');
|
|
77
119
|
return;
|
|
78
120
|
}
|
|
@@ -88,7 +130,6 @@ export default function Topbar({ templateContext }: TopbarProps) {
|
|
|
88
130
|
},
|
|
89
131
|
});
|
|
90
132
|
|
|
91
|
-
localStorage.setItem(LS_KEY, JSON.stringify(templateState));
|
|
92
133
|
toast.success('Template salvo');
|
|
93
134
|
};
|
|
94
135
|
|
|
@@ -99,6 +99,7 @@ type CreateCertificateTemplatePayload = {
|
|
|
99
99
|
type UpdateCertificateTemplatePayload = {
|
|
100
100
|
name: string;
|
|
101
101
|
description?: string;
|
|
102
|
+
status: TemplateStatus;
|
|
102
103
|
};
|
|
103
104
|
|
|
104
105
|
const PAGE_SIZES = [6, 12, 24];
|
|
@@ -114,6 +115,7 @@ const updateTemplateSchema = (t: (key: string) => string) =>
|
|
|
114
115
|
z.object({
|
|
115
116
|
name: z.string().trim().min(1, t('editSheet.validation.required')),
|
|
116
117
|
description: z.string().trim().optional(),
|
|
118
|
+
status: z.enum(['draft', 'active', 'inactive']),
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
type CreateTemplateFormValues = z.infer<
|
|
@@ -173,6 +175,7 @@ export default function ModelsPage() {
|
|
|
173
175
|
defaultValues: {
|
|
174
176
|
name: '',
|
|
175
177
|
description: '',
|
|
178
|
+
status: 'draft',
|
|
176
179
|
},
|
|
177
180
|
});
|
|
178
181
|
|
|
@@ -304,6 +307,7 @@ export default function ModelsPage() {
|
|
|
304
307
|
editForm.reset({
|
|
305
308
|
name: '',
|
|
306
309
|
description: '',
|
|
310
|
+
status: 'draft',
|
|
307
311
|
});
|
|
308
312
|
setEditingTemplateId(null);
|
|
309
313
|
}
|
|
@@ -325,6 +329,7 @@ export default function ModelsPage() {
|
|
|
325
329
|
editForm.reset({
|
|
326
330
|
name: template.name,
|
|
327
331
|
description: template.description ?? '',
|
|
332
|
+
status: template.status,
|
|
328
333
|
});
|
|
329
334
|
setIsEditSheetOpen(true);
|
|
330
335
|
}
|
|
@@ -410,6 +415,7 @@ export default function ModelsPage() {
|
|
|
410
415
|
const payload: UpdateCertificateTemplatePayload = {
|
|
411
416
|
name,
|
|
412
417
|
description: values.description?.trim() || undefined,
|
|
418
|
+
status: values.status,
|
|
413
419
|
};
|
|
414
420
|
|
|
415
421
|
try {
|
|
@@ -825,6 +831,32 @@ export default function ModelsPage() {
|
|
|
825
831
|
/>
|
|
826
832
|
</div>
|
|
827
833
|
|
|
834
|
+
<div className="space-y-2">
|
|
835
|
+
<p className="text-sm font-medium">
|
|
836
|
+
{t('editSheet.fields.status')}
|
|
837
|
+
</p>
|
|
838
|
+
<Controller
|
|
839
|
+
name="status"
|
|
840
|
+
control={editForm.control}
|
|
841
|
+
render={({ field }) => (
|
|
842
|
+
<Select value={field.value} onValueChange={field.onChange}>
|
|
843
|
+
<SelectTrigger className="w-full">
|
|
844
|
+
<SelectValue placeholder={t('editSheet.fields.status')} />
|
|
845
|
+
</SelectTrigger>
|
|
846
|
+
<SelectContent>
|
|
847
|
+
<SelectItem value="draft">{t('status.draft')}</SelectItem>
|
|
848
|
+
<SelectItem value="active">
|
|
849
|
+
{t('status.active')}
|
|
850
|
+
</SelectItem>
|
|
851
|
+
<SelectItem value="inactive">
|
|
852
|
+
{t('status.inactive')}
|
|
853
|
+
</SelectItem>
|
|
854
|
+
</SelectContent>
|
|
855
|
+
</Select>
|
|
856
|
+
)}
|
|
857
|
+
/>
|
|
858
|
+
</div>
|
|
859
|
+
|
|
828
860
|
{editForm.formState.errors.name?.message ? (
|
|
829
861
|
<p className="text-sm text-destructive">
|
|
830
862
|
{editForm.formState.errors.name.message}
|
|
@@ -2171,6 +2171,7 @@
|
|
|
2171
2171
|
"cards": {
|
|
2172
2172
|
"status": "Status",
|
|
2173
2173
|
"updatedAt": "Updated",
|
|
2174
|
+
"noDescription": "No description",
|
|
2174
2175
|
"actions": {
|
|
2175
2176
|
"menuLabel": "More actions",
|
|
2176
2177
|
"editTemplate": "Edit template",
|
|
@@ -2205,7 +2206,8 @@
|
|
|
2205
2206
|
"description": "Update the template basic information.",
|
|
2206
2207
|
"fields": {
|
|
2207
2208
|
"name": "Name",
|
|
2208
|
-
"description": "Description"
|
|
2209
|
+
"description": "Description",
|
|
2210
|
+
"status": "Status"
|
|
2209
2211
|
},
|
|
2210
2212
|
"placeholders": {
|
|
2211
2213
|
"name": "e.g. Corporate Certificate",
|
|
@@ -2178,6 +2178,7 @@
|
|
|
2178
2178
|
"cards": {
|
|
2179
2179
|
"status": "Status",
|
|
2180
2180
|
"updatedAt": "Atualizado",
|
|
2181
|
+
"noDescription": "Sem descrição",
|
|
2181
2182
|
"actions": {
|
|
2182
2183
|
"menuLabel": "Mais ações",
|
|
2183
2184
|
"editTemplate": "Editar template",
|
|
@@ -2212,7 +2213,8 @@
|
|
|
2212
2213
|
"description": "Atualize os dados básicos do template.",
|
|
2213
2214
|
"fields": {
|
|
2214
2215
|
"name": "Nome",
|
|
2215
|
-
"description": "Descrição"
|
|
2216
|
+
"description": "Descrição",
|
|
2217
|
+
"status": "Status"
|
|
2216
2218
|
},
|
|
2217
2219
|
"placeholders": {
|
|
2218
2220
|
"name": "Ex.: Certificado Corporativo",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/lms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.310",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
-
"@hed-hog/api-prisma": "0.0.6",
|
|
13
12
|
"@hed-hog/api-types": "0.0.1",
|
|
14
|
-
"@hed-hog/
|
|
13
|
+
"@hed-hog/api-prisma": "0.0.6",
|
|
15
14
|
"@hed-hog/api-pagination": "0.0.7",
|
|
16
|
-
"@hed-hog/core": "0.0.309",
|
|
17
|
-
"@hed-hog/api-locale": "0.0.14",
|
|
18
15
|
"@hed-hog/api": "0.0.6",
|
|
19
|
-
"@hed-hog/
|
|
20
|
-
"@hed-hog/
|
|
16
|
+
"@hed-hog/contact": "0.0.310",
|
|
17
|
+
"@hed-hog/api-locale": "0.0.14",
|
|
18
|
+
"@hed-hog/finance": "0.0.310",
|
|
19
|
+
"@hed-hog/core": "0.0.310",
|
|
20
|
+
"@hed-hog/category": "0.0.310"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|