proteum 1.0.0-1
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/.dockerignore +10 -0
- package/Rte.zip +0 -0
- package/cli/app/config.ts +54 -0
- package/cli/app/index.ts +195 -0
- package/cli/bin.js +11 -0
- package/cli/commands/build.ts +34 -0
- package/cli/commands/deploy/app.ts +29 -0
- package/cli/commands/deploy/web.ts +60 -0
- package/cli/commands/dev.ts +109 -0
- package/cli/commands/init.ts +85 -0
- package/cli/compiler/client/identite.ts +72 -0
- package/cli/compiler/client/index.ts +334 -0
- package/cli/compiler/common/babel/index.ts +170 -0
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +579 -0
- package/cli/compiler/common/babel/routes/imports.ts +127 -0
- package/cli/compiler/common/babel/routes/routes.ts +1130 -0
- package/cli/compiler/common/files/autres.ts +39 -0
- package/cli/compiler/common/files/images.ts +35 -0
- package/cli/compiler/common/files/style.ts +78 -0
- package/cli/compiler/common/index.ts +154 -0
- package/cli/compiler/index.ts +532 -0
- package/cli/compiler/server/index.ts +211 -0
- package/cli/index.ts +189 -0
- package/cli/paths.ts +165 -0
- package/cli/print.ts +12 -0
- package/cli/tsconfig.json +38 -0
- package/cli/utils/index.ts +22 -0
- package/cli/utils/keyboard.ts +78 -0
- package/client/app/component.tsx +54 -0
- package/client/app/index.ts +142 -0
- package/client/app/service.ts +34 -0
- package/client/app.tsconfig.json +28 -0
- package/client/components/Button.tsx +298 -0
- package/client/components/Dialog/Manager.tsx +309 -0
- package/client/components/Dialog/card.tsx +208 -0
- package/client/components/Dialog/index.less +151 -0
- package/client/components/Dialog/status.less +176 -0
- package/client/components/Dialog/status.tsx +48 -0
- package/client/components/index.ts +2 -0
- package/client/components/types.d.ts +3 -0
- package/client/data/input.ts +32 -0
- package/client/global.d.ts +5 -0
- package/client/hooks.ts +22 -0
- package/client/index.ts +6 -0
- package/client/pages/_layout/index.less +6 -0
- package/client/pages/_layout/index.tsx +43 -0
- package/client/pages/bug.tsx.old +60 -0
- package/client/pages/useHeader.tsx +50 -0
- package/client/services/captcha/index.ts +67 -0
- package/client/services/router/components/Link.tsx +46 -0
- package/client/services/router/components/Page.tsx +55 -0
- package/client/services/router/components/router.tsx +218 -0
- package/client/services/router/index.tsx +521 -0
- package/client/services/router/request/api.ts +267 -0
- package/client/services/router/request/history.ts +5 -0
- package/client/services/router/request/index.ts +53 -0
- package/client/services/router/request/multipart.ts +147 -0
- package/client/services/router/response/index.tsx +128 -0
- package/client/services/router/response/page.ts +86 -0
- package/client/services/socket/index.ts +147 -0
- package/client/utils/dom.ts +77 -0
- package/common/app/index.ts +9 -0
- package/common/data/chaines/index.ts +54 -0
- package/common/data/dates.ts +179 -0
- package/common/data/markdown.ts +73 -0
- package/common/data/rte/nodes.ts +83 -0
- package/common/data/stats.ts +90 -0
- package/common/errors/index.tsx +326 -0
- package/common/router/index.ts +213 -0
- package/common/router/layouts.ts +93 -0
- package/common/router/register.ts +55 -0
- package/common/router/request/api.ts +77 -0
- package/common/router/request/index.ts +35 -0
- package/common/router/response/index.ts +45 -0
- package/common/router/response/page.ts +128 -0
- package/common/utils/rte.ts +183 -0
- package/common/utils.ts +7 -0
- package/doc/TODO.md +71 -0
- package/doc/front/router.md +27 -0
- package/doc/workspace/workspace.png +0 -0
- package/doc/workspace/workspace2.png +0 -0
- package/doc/workspace/workspace_26.01.22.png +0 -0
- package/package.json +171 -0
- package/server/app/commands.ts +141 -0
- package/server/app/container/config.ts +203 -0
- package/server/app/container/console/index.ts +550 -0
- package/server/app/container/index.ts +137 -0
- package/server/app/index.ts +273 -0
- package/server/app/service/container.ts +88 -0
- package/server/app/service/index.ts +235 -0
- package/server/app.tsconfig.json +28 -0
- package/server/context.ts +4 -0
- package/server/index.ts +4 -0
- package/server/services/auth/index.ts +250 -0
- package/server/services/auth/old.ts +277 -0
- package/server/services/auth/router/index.ts +95 -0
- package/server/services/auth/router/request.ts +54 -0
- package/server/services/auth/router/service.json +6 -0
- package/server/services/auth/service.json +6 -0
- package/server/services/cache/commands.ts +41 -0
- package/server/services/cache/index.ts +297 -0
- package/server/services/cache/service.json +6 -0
- package/server/services/cron/CronTask.ts +86 -0
- package/server/services/cron/index.ts +112 -0
- package/server/services/cron/service.json +6 -0
- package/server/services/disks/driver.ts +103 -0
- package/server/services/disks/drivers/local/index.ts +188 -0
- package/server/services/disks/drivers/local/service.json +6 -0
- package/server/services/disks/drivers/s3/index.ts +301 -0
- package/server/services/disks/drivers/s3/service.json +6 -0
- package/server/services/disks/index.ts +90 -0
- package/server/services/disks/service.json +6 -0
- package/server/services/email/index.ts +188 -0
- package/server/services/email/utils.ts +53 -0
- package/server/services/fetch/index.ts +201 -0
- package/server/services/fetch/service.json +7 -0
- package/server/services/models.7z +0 -0
- package/server/services/prisma/Facet.ts +142 -0
- package/server/services/prisma/index.ts +201 -0
- package/server/services/prisma/service.json +6 -0
- package/server/services/router/http/index.ts +217 -0
- package/server/services/router/http/multipart.ts +102 -0
- package/server/services/router/http/session.ts.old +40 -0
- package/server/services/router/index.ts +801 -0
- package/server/services/router/request/api.ts +87 -0
- package/server/services/router/request/index.ts +184 -0
- package/server/services/router/request/service.ts +21 -0
- package/server/services/router/request/validation/zod.ts +180 -0
- package/server/services/router/response/index.ts +338 -0
- package/server/services/router/response/mask/Filter.ts +323 -0
- package/server/services/router/response/mask/index.ts +60 -0
- package/server/services/router/response/mask/selecteurs.ts +92 -0
- package/server/services/router/response/page/document.tsx +160 -0
- package/server/services/router/response/page/index.tsx +196 -0
- package/server/services/router/service.json +6 -0
- package/server/services/router/service.ts +36 -0
- package/server/services/schema/index.ts +44 -0
- package/server/services/schema/request.ts +49 -0
- package/server/services/schema/router/index.ts +28 -0
- package/server/services/schema/router/service.json +6 -0
- package/server/services/schema/service.json +6 -0
- package/server/services/security/encrypt/aes/index.ts +85 -0
- package/server/services/security/encrypt/aes/service.json +6 -0
- package/server/services/socket/index.ts +162 -0
- package/server/services/socket/scope.ts +226 -0
- package/server/services/socket/service.json +6 -0
- package/server/services_old/SocketClient.ts +92 -0
- package/server/services_old/Token.old.ts +97 -0
- package/server/utils/slug.ts +79 -0
- package/tsconfig.common.json +45 -0
- package/tsconfig.json +3 -0
- package/types/aliases.d.ts +54 -0
- package/types/global/modules.d.ts +49 -0
- package/types/global/utils.d.ts +103 -0
- package/types/icons.d.ts +1 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// https://github.com/Kamonlojn/svg-icons-animate
|
|
2
|
+
|
|
3
|
+
* {
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.svg-box {
|
|
9
|
+
display:block;
|
|
10
|
+
position: relative;
|
|
11
|
+
width:14.15rem;
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
|
|
14
|
+
> svg {
|
|
15
|
+
stroke: #fff;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/*.green-stroke {
|
|
20
|
+
stroke:#7CB342;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.red-stroke {
|
|
24
|
+
stroke: #FF6245;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.yellow-stroke {
|
|
28
|
+
stroke: #FFC107;
|
|
29
|
+
}*/
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
.circular circle.path {
|
|
33
|
+
stroke-dasharray: 330;
|
|
34
|
+
stroke-dashoffset: 0;
|
|
35
|
+
stroke-linecap: round;
|
|
36
|
+
opacity: 0.4;
|
|
37
|
+
animation: 0.7s draw-circle ease-out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/*------- Checkmark ---------*/
|
|
41
|
+
.checkmark{
|
|
42
|
+
stroke-width: 6.25;
|
|
43
|
+
stroke-linecap: round;
|
|
44
|
+
position:absolute;
|
|
45
|
+
top: 56px;
|
|
46
|
+
left: 49px;
|
|
47
|
+
width: 52px;
|
|
48
|
+
height: 40px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.checkmark path {
|
|
52
|
+
animation: 1s draw-check ease-out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@keyframes draw-circle {
|
|
56
|
+
0% {
|
|
57
|
+
stroke-dasharray: 0,330;
|
|
58
|
+
stroke-dashoffset: 0;
|
|
59
|
+
opacity: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
80% {
|
|
63
|
+
stroke-dasharray: 330,330;
|
|
64
|
+
stroke-dashoffset: 0;
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
100%{
|
|
69
|
+
opacity: 0.4;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@keyframes draw-check {
|
|
74
|
+
0% {
|
|
75
|
+
stroke-dasharray: 49,80;
|
|
76
|
+
stroke-dashoffset: 48;
|
|
77
|
+
opacity: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
50% {
|
|
81
|
+
stroke-dasharray: 49,80;
|
|
82
|
+
stroke-dashoffset: 48;
|
|
83
|
+
opacity: 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
100% {
|
|
87
|
+
stroke-dasharray: 130,80;
|
|
88
|
+
stroke-dashoffset: 48;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/*---------- Cross ----------*/
|
|
93
|
+
|
|
94
|
+
.cross {
|
|
95
|
+
stroke-width:6.25;
|
|
96
|
+
stroke-linecap: round;
|
|
97
|
+
position: absolute;
|
|
98
|
+
top: 54px;
|
|
99
|
+
left: 54px;
|
|
100
|
+
width: 40px;
|
|
101
|
+
height: 40px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.cross .first-line {
|
|
105
|
+
animation: 0.7s draw-first-line ease-out;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.cross .second-line {
|
|
109
|
+
animation: 0.7s draw-second-line ease-out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@keyframes draw-first-line {
|
|
113
|
+
0% {
|
|
114
|
+
stroke-dasharray: 0,56;
|
|
115
|
+
stroke-dashoffset: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
50% {
|
|
119
|
+
stroke-dasharray: 0,56;
|
|
120
|
+
stroke-dashoffset: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
100% {
|
|
124
|
+
stroke-dasharray: 56,330;
|
|
125
|
+
stroke-dashoffset: 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@keyframes draw-second-line {
|
|
130
|
+
0% {
|
|
131
|
+
stroke-dasharray: 0,55;
|
|
132
|
+
stroke-dashoffset: 1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
50% {
|
|
136
|
+
stroke-dasharray: 0,55;
|
|
137
|
+
stroke-dashoffset: 1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
100% {
|
|
141
|
+
stroke-dasharray: 55,0;
|
|
142
|
+
stroke-dashoffset: 70;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.alert-sign {
|
|
147
|
+
stroke-width:6.25;
|
|
148
|
+
stroke-linecap: round;
|
|
149
|
+
position: absolute;
|
|
150
|
+
top: 40px;
|
|
151
|
+
left: 68px;
|
|
152
|
+
width: 1.25rem;
|
|
153
|
+
height: 70px;
|
|
154
|
+
animation: 0.5s alert-sign-bounce cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.alert-sign .dot {
|
|
158
|
+
stroke:none;
|
|
159
|
+
fill: #FFC107;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@keyframes alert-sign-bounce {
|
|
163
|
+
0% {
|
|
164
|
+
transform: scale(0);
|
|
165
|
+
opacity: 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
50% {
|
|
169
|
+
transform: scale(0);
|
|
170
|
+
opacity: 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
100% {
|
|
174
|
+
transform: scale(1);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export const SuccessAnimation = (
|
|
4
|
+
<div class="svg-box">
|
|
5
|
+
<svg class="circular green-stroke">
|
|
6
|
+
<circle class="path" cx="75" cy="75" r="50" fill="none" stroke-width="5" stroke-miterlimit="10" />
|
|
7
|
+
</svg>
|
|
8
|
+
<svg class="checkmark green-stroke">
|
|
9
|
+
<g transform="matrix(0.79961,8.65821e-32,8.39584e-32,0.79961,-489.57,-205.679)">
|
|
10
|
+
<path class="checkmark__check" fill="none" d="M616.306,283.025L634.087,300.805L673.361,261.53" />
|
|
11
|
+
</g>
|
|
12
|
+
</svg>
|
|
13
|
+
</div>
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
export const WarningAnimation = (
|
|
17
|
+
<div class="svg-box">
|
|
18
|
+
<svg class="circular yellow-stroke">
|
|
19
|
+
<circle class="path" cx="75" cy="75" r="50" fill="none" stroke-width="5" stroke-miterlimit="10" />
|
|
20
|
+
</svg>
|
|
21
|
+
<svg class="alert-sign yellow-stroke">
|
|
22
|
+
<g transform="matrix(1,0,0,1,-615.516,-257.346)">
|
|
23
|
+
<g transform="matrix(0.56541,-0.56541,0.56541,0.56541,93.7153,495.69)">
|
|
24
|
+
<path class="line" d="M634.087,300.805L673.361,261.53" fill="none" />
|
|
25
|
+
</g>
|
|
26
|
+
<g transform="matrix(2.27612,-2.46519e-32,0,2.27612,-792.339,-404.147)">
|
|
27
|
+
<circle class="dot" cx="621.52" cy="316.126" r="1.318" />
|
|
28
|
+
</g>
|
|
29
|
+
</g>
|
|
30
|
+
</svg>
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
export const ErrorAnimation = (
|
|
35
|
+
<div class="svg-box">
|
|
36
|
+
<svg class="circular red-stroke">
|
|
37
|
+
<circle class="path" cx="75" cy="75" r="50" fill="none" stroke-width="5" stroke-miterlimit="10" />
|
|
38
|
+
</svg>
|
|
39
|
+
<svg class="cross red-stroke">
|
|
40
|
+
<g transform="matrix(0.79961,8.65821e-32,8.39584e-32,0.79961,-502.652,-204.518)">
|
|
41
|
+
<path class="first-line" d="M634.087,300.805L673.361,261.53" fill="none" />
|
|
42
|
+
</g>
|
|
43
|
+
<g transform="matrix(-1.28587e-16,-0.79961,0.79961,-1.28587e-16,-204.752,543.031)">
|
|
44
|
+
<path class="second-line" d="M634.087,300.805L673.361,261.53" />
|
|
45
|
+
</g>
|
|
46
|
+
</svg>
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Libs métier
|
|
6
|
+
import buildValidators, { champ } from '@common/data/input/validators/build';
|
|
7
|
+
import { validateurFichier, TOptsValidateurFichier } from '@common/data/input/validators/basic';
|
|
8
|
+
|
|
9
|
+
/*----------------------------------
|
|
10
|
+
- VALIDATEURS
|
|
11
|
+
----------------------------------*/
|
|
12
|
+
|
|
13
|
+
export default buildValidators({
|
|
14
|
+
|
|
15
|
+
file: ({ ...opts }: TOptsValidateurFichier & {}) => champ<object>('fichier', {
|
|
16
|
+
...opts,
|
|
17
|
+
valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
|
|
18
|
+
|
|
19
|
+
console.log('VALIDER FICHIER COTÉ CLIENT', val);
|
|
20
|
+
|
|
21
|
+
// Chaine = url ancien fichier = conservation = sera ignoré coté serveur
|
|
22
|
+
if (typeof val === 'string')
|
|
23
|
+
return val;
|
|
24
|
+
|
|
25
|
+
// Validation universelle
|
|
26
|
+
val = await validateurFichier(opts, val, donneesSaisie, donneesRetour);
|
|
27
|
+
|
|
28
|
+
return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
});
|
package/client/hooks.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ComponentChild } from 'preact';
|
|
3
|
+
|
|
4
|
+
// Hooks
|
|
5
|
+
/*export { default as useState } from '@client/hooks/useState';
|
|
6
|
+
export type { TActions as TActionsState } from '@client/hooks/useState';
|
|
7
|
+
export { default as useComponent } from '@client/hooks/useComponent';
|
|
8
|
+
export { default as useScript } from '@client/hooks/useScript';*/
|
|
9
|
+
|
|
10
|
+
// Utils
|
|
11
|
+
export const Switch = (val: string | number, options: { [cle: string]: ComponentChild }) => {
|
|
12
|
+
return (val in options) ? options[val] : null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useState = <TData extends TObjetDonnees>(initial: TData): [
|
|
16
|
+
TData,
|
|
17
|
+
(data: Partial<TData>) => void
|
|
18
|
+
] => {
|
|
19
|
+
const [state, setState] = React.useState<TData>(initial);
|
|
20
|
+
const setPartialState = (data: Partial<TData>) => setState(current => ({ ...current, ...data }));
|
|
21
|
+
return [state, setPartialState]
|
|
22
|
+
}
|
package/client/index.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
// Core
|
|
10
|
+
import RouterComponent from '@client/services/router/components/router';
|
|
11
|
+
import { ClientContext } from '@/client/context';
|
|
12
|
+
|
|
13
|
+
// Core components
|
|
14
|
+
|
|
15
|
+
// Resources
|
|
16
|
+
import "./index.less";
|
|
17
|
+
|
|
18
|
+
/*----------------------------------
|
|
19
|
+
- TYPES
|
|
20
|
+
----------------------------------*/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/*----------------------------------
|
|
24
|
+
- COMPOSANT
|
|
25
|
+
----------------------------------*/
|
|
26
|
+
export default function App ({ context, menu }: {
|
|
27
|
+
context: ClientContext,
|
|
28
|
+
menu: ComponentChild
|
|
29
|
+
}) {
|
|
30
|
+
|
|
31
|
+
const { Router, page, toast } = context;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div id="internaLlayout">
|
|
35
|
+
|
|
36
|
+
<div class="center row al-fill">
|
|
37
|
+
|
|
38
|
+
<RouterComponent service={Router} />
|
|
39
|
+
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
// Npm
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
// Core components
|
|
8
|
+
import { Button, Input } from '@client/components';
|
|
9
|
+
import Card, { Props as CardProps } from '@client/components/Dialog/card';
|
|
10
|
+
|
|
11
|
+
// Core libs
|
|
12
|
+
import useContext from '@/client/context';
|
|
13
|
+
|
|
14
|
+
/*----------------------------------
|
|
15
|
+
- TYPES
|
|
16
|
+
----------------------------------*/
|
|
17
|
+
|
|
18
|
+
export default ({ ...self }: {} & CardProps) => {
|
|
19
|
+
|
|
20
|
+
const { api, modal, clientBug } = useContext();
|
|
21
|
+
|
|
22
|
+
const [observation, setObservation] = React.useState("");
|
|
23
|
+
const [before, setBefore] = React.useState("");
|
|
24
|
+
|
|
25
|
+
const send = () => clientBug({ observation, before }).then(() =>
|
|
26
|
+
modal.success("Thanks You !", `Your bug report will be review in the next 12 hours.`).then(() =>
|
|
27
|
+
self.close(true)
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const close = () => modal.confirm("Cancel your report ?", "All your changes will not be saved.").then(close =>
|
|
32
|
+
close && self.close(true)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
self.onClose = close
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Card {...self} title="Report a problem" footer={<>
|
|
39
|
+
|
|
40
|
+
<Button onClick={() => close()}>
|
|
41
|
+
Cancel
|
|
42
|
+
</Button>
|
|
43
|
+
|
|
44
|
+
<Button type="primary" onClick={send}>
|
|
45
|
+
Send Report
|
|
46
|
+
</Button>
|
|
47
|
+
|
|
48
|
+
</>}>
|
|
49
|
+
|
|
50
|
+
<p>What's the problem ?</p>
|
|
51
|
+
|
|
52
|
+
<Input type="longtext" title="Description of the problem" value={observation} onChange={setObservation} />
|
|
53
|
+
|
|
54
|
+
<p>What did you do just before the problem occurs ?</p>
|
|
55
|
+
|
|
56
|
+
<Input type="longtext" title="How the problem occured ?" value={before} onChange={setBefore} />
|
|
57
|
+
|
|
58
|
+
</Card>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Core
|
|
6
|
+
import useContext from '@/client/context';
|
|
7
|
+
|
|
8
|
+
/*----------------------------------
|
|
9
|
+
- TYPES
|
|
10
|
+
----------------------------------*/
|
|
11
|
+
export type Props = {
|
|
12
|
+
id?: string,
|
|
13
|
+
focus?: boolean,
|
|
14
|
+
jail?: boolean,
|
|
15
|
+
error?: boolean,
|
|
16
|
+
|
|
17
|
+
title: string,
|
|
18
|
+
subtitle?: string,
|
|
19
|
+
description?: string,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*----------------------------------
|
|
23
|
+
- HOOK
|
|
24
|
+
----------------------------------*/
|
|
25
|
+
export default ({ id, title, subtitle, focus, jail, description }: Props) => {
|
|
26
|
+
|
|
27
|
+
let { page } = useContext();
|
|
28
|
+
|
|
29
|
+
// page est supposé ne pas être undefined
|
|
30
|
+
if (!page)
|
|
31
|
+
return;
|
|
32
|
+
|
|
33
|
+
// SEO Title
|
|
34
|
+
page.title = title;
|
|
35
|
+
if (subtitle !== undefined)
|
|
36
|
+
page.title += ' | ' + subtitle;
|
|
37
|
+
|
|
38
|
+
// SEO Description
|
|
39
|
+
if (description !== undefined)
|
|
40
|
+
page.description = description;
|
|
41
|
+
|
|
42
|
+
page.bodyId = page.bodyId || id || '';
|
|
43
|
+
|
|
44
|
+
if (focus)
|
|
45
|
+
page.bodyClass.add('focus');
|
|
46
|
+
|
|
47
|
+
if (jail)
|
|
48
|
+
page.bodyClass.add('jail');
|
|
49
|
+
|
|
50
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import loadScript from 'load-script';
|
|
7
|
+
|
|
8
|
+
/*----------------------------------
|
|
9
|
+
- SERVICE
|
|
10
|
+
----------------------------------*/
|
|
11
|
+
export default class Recaptcha {
|
|
12
|
+
|
|
13
|
+
private idClientCaptcha: string | null = null;
|
|
14
|
+
public init(): Promise<void> {
|
|
15
|
+
const idConteneurBadge = 'badge-recaptcha';
|
|
16
|
+
return new Promise((resolve: Function, reject: Function) => {
|
|
17
|
+
|
|
18
|
+
// Déjà chargé
|
|
19
|
+
if (this.idClientCaptcha !== null)
|
|
20
|
+
return resolve();
|
|
21
|
+
|
|
22
|
+
loadScript('https://www.google.com/recaptcha/api.js?render=explicit', (err/*, script*/) => {
|
|
23
|
+
|
|
24
|
+
if (err) {
|
|
25
|
+
reject(err);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
grecaptcha.ready(() => {
|
|
30
|
+
|
|
31
|
+
const conteneur = document.getElementById(idConteneurBadge);
|
|
32
|
+
|
|
33
|
+
if (!conteneur)
|
|
34
|
+
throw new Error("Conteneur badge recaptcha pas trouvé");
|
|
35
|
+
|
|
36
|
+
if (this.idClientCaptcha === null) {
|
|
37
|
+
if (conteneur.dataset.flottant)
|
|
38
|
+
this.idClientCaptcha = grecaptcha.render(idConteneurBadge, {
|
|
39
|
+
'sitekey': this.app.apis.recaptcha.pub,
|
|
40
|
+
'size': 'invisible'
|
|
41
|
+
});
|
|
42
|
+
else
|
|
43
|
+
this.idClientCaptcha = grecaptcha.render(idConteneurBadge, {
|
|
44
|
+
'sitekey': this.app.apis.recaptcha.pub,
|
|
45
|
+
'badge': 'inline',
|
|
46
|
+
'size': 'invisible'
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (this.idClientCaptcha !== null)
|
|
51
|
+
resolve();
|
|
52
|
+
else
|
|
53
|
+
reject("Attendez que la page soit complètement chargée. Si c'est déjà le cas, rechargez la page.");
|
|
54
|
+
});
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public async check(action: string): Promise<string> {
|
|
60
|
+
|
|
61
|
+
await this.init();
|
|
62
|
+
|
|
63
|
+
const token = grecaptcha.execute(this.idClientCaptcha, { action: action });
|
|
64
|
+
|
|
65
|
+
return token;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ComponentChild } from 'preact';
|
|
8
|
+
import { history } from '../request/history';
|
|
9
|
+
|
|
10
|
+
export const shouldOpenNewTab = (url: string, target?: string) => url && (
|
|
11
|
+
target !== undefined
|
|
12
|
+
||
|
|
13
|
+
!['/', '#'].includes(url[0])
|
|
14
|
+
||
|
|
15
|
+
url.startsWith('//')
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
/*----------------------------------
|
|
19
|
+
- COMPONENT
|
|
20
|
+
----------------------------------*/
|
|
21
|
+
// Simple link
|
|
22
|
+
export const Link = ({ to, ...props }: {
|
|
23
|
+
to: string,
|
|
24
|
+
children?: ComponentChild,
|
|
25
|
+
class?: string,
|
|
26
|
+
className?: string
|
|
27
|
+
} & React.HTMLProps<HTMLAnchorElement>) => {
|
|
28
|
+
|
|
29
|
+
const openNewTab = shouldOpenNewTab(to, props.target);
|
|
30
|
+
|
|
31
|
+
// External = open in new tab by default
|
|
32
|
+
if (openNewTab)
|
|
33
|
+
props.target = '_blank';
|
|
34
|
+
// Otherwise, propagate to the router
|
|
35
|
+
else
|
|
36
|
+
props.onClick = (e) => {
|
|
37
|
+
history?.push(to);
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<a {...props} href={to} />
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
// Npm
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
// Core
|
|
8
|
+
import useContext from '@/client/context';
|
|
9
|
+
|
|
10
|
+
// Specific
|
|
11
|
+
import type Page from '../response/page';
|
|
12
|
+
|
|
13
|
+
/*----------------------------------
|
|
14
|
+
- PAGE STATE
|
|
15
|
+
----------------------------------*/
|
|
16
|
+
|
|
17
|
+
export default ({ page }: { page: Page }) => {
|
|
18
|
+
|
|
19
|
+
/*----------------------------------
|
|
20
|
+
- CONTEXT
|
|
21
|
+
----------------------------------*/
|
|
22
|
+
const context = useContext();
|
|
23
|
+
|
|
24
|
+
// Bind data
|
|
25
|
+
const [apiData, setApiData] = React.useState<{[k: string]: any} | null>( page.data || {});
|
|
26
|
+
page.setAllData = setApiData;
|
|
27
|
+
const fullData = {
|
|
28
|
+
...context.data,
|
|
29
|
+
...apiData
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Temporary fix: context.page may not be updated at this stage
|
|
33
|
+
// Seems to be the case when we change page, but still same page component with different data
|
|
34
|
+
// TODO: ensure these updated are made every tume we change page / context
|
|
35
|
+
context.page = page;
|
|
36
|
+
context.data = fullData;
|
|
37
|
+
context.context = context;
|
|
38
|
+
|
|
39
|
+
// Page component has not changed, but data were updated (ex: url parameters change)
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
|
|
42
|
+
setApiData(page.data);
|
|
43
|
+
|
|
44
|
+
}, [page.data]);
|
|
45
|
+
|
|
46
|
+
/*----------------------------------
|
|
47
|
+
- RENDER
|
|
48
|
+
----------------------------------*/
|
|
49
|
+
// Make request parameters and api data accessible from the page component
|
|
50
|
+
return page.renderer ? (
|
|
51
|
+
|
|
52
|
+
<page.renderer {...context} />
|
|
53
|
+
|
|
54
|
+
) : <>Renderer missing</>
|
|
55
|
+
}
|