5htp-core 0.1.0 → 0.1.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/package.json +7 -5
- package/src/client/assets/css/components/button.less +7 -1
- package/src/client/assets/css/components/card.less +34 -14
- package/src/client/assets/css/components/components.less +4 -2
- package/src/client/assets/css/components/table.less +2 -1
- package/src/client/assets/css/medias.less +26 -3
- package/src/client/assets/css/text/titres.less +6 -2
- package/src/client/assets/css/theme.less +6 -4
- package/src/client/components/Card/index.less +0 -0
- package/src/client/components/Card/index.tsx +87 -0
- package/src/client/components/Row/index.less +65 -0
- package/src/client/components/Row/index.tsx +72 -0
- package/src/client/components/Table/index.tsx +26 -25
- package/src/client/components/button.tsx +1 -1
- package/src/server/routes/auth.ts +3 -3
- package/src/server/services/auth/base.ts +22 -8
- package/src/server/services/console/bugReporter.ts +103 -24
- package/src/server/services/console/index.ts +21 -0
- package/src/server/services/email/index.ts +24 -11
- package/src/server/services/router/index.ts +4 -5
- package/src/server/services/router/request/services/auth.ts +72 -34
- package/src/server/services/router/request/services/tracking.ts +1 -1
- package/src/server/services/email/transports/local.ts +0 -102
- package/src/server/services/email/transports/mailjet.ts +0 -75
- package/src/server/services/email/transports/sendgrid.ts +0 -44
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "5-HTP, scientifically called 5-Hydroxytryptophan, is the precursor of happiness neurotransmitter.",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -72,9 +72,7 @@
|
|
|
72
72
|
"uuid-by-string": "^3.0.4",
|
|
73
73
|
"validator": "^13.7.0",
|
|
74
74
|
"ws": "^8.2.2",
|
|
75
|
-
"yaml": "^1.10.2"
|
|
76
|
-
"preact": "^10.5.15",
|
|
77
|
-
"preact-render-to-string": "^5.1.19"
|
|
75
|
+
"yaml": "^1.10.2"
|
|
78
76
|
},
|
|
79
77
|
"devDependencies": {
|
|
80
78
|
"@types/cookie": "^0.4.1",
|
|
@@ -85,5 +83,9 @@
|
|
|
85
83
|
"@types/universal-analytics": "^0.4.5",
|
|
86
84
|
"@types/webpack-env": "^1.16.2",
|
|
87
85
|
"@types/ws": "^7.4.7"
|
|
88
|
-
}
|
|
86
|
+
},
|
|
87
|
+
"peerDependencies": {
|
|
88
|
+
"preact": "^10.5.15",
|
|
89
|
+
"preact-render-to-string": "^5.1.19"
|
|
90
|
+
}
|
|
89
91
|
}
|
|
@@ -194,6 +194,12 @@
|
|
|
194
194
|
height: auto;
|
|
195
195
|
width: auto;
|
|
196
196
|
padding: 0;
|
|
197
|
+
|
|
198
|
+
&,
|
|
199
|
+
&:hover {
|
|
200
|
+
background: none;
|
|
201
|
+
box-shadow: none;
|
|
202
|
+
}
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
205
|
|
|
@@ -211,7 +217,7 @@ ul.row {
|
|
|
211
217
|
color: var(--cTxtBase);
|
|
212
218
|
box-shadow: none;
|
|
213
219
|
border: none;
|
|
214
|
-
width: 100%;
|
|
220
|
+
//width: 100%;
|
|
215
221
|
background: transparent;
|
|
216
222
|
|
|
217
223
|
&.selected,
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- CONFIG
|
|
3
|
+
----------------------------------*/
|
|
1
4
|
@import (reference) "../theme.less";
|
|
2
5
|
|
|
6
|
+
@cardPadding: @spacing * 1.5;
|
|
7
|
+
@cardPaddingLong: @spacing * 2;
|
|
8
|
+
|
|
9
|
+
/*----------------------------------
|
|
10
|
+
- COMPONENTS
|
|
11
|
+
----------------------------------*/
|
|
3
12
|
.card,
|
|
4
13
|
.msg {
|
|
5
14
|
position: relative; // For .overlay
|
|
@@ -10,7 +19,15 @@
|
|
|
10
19
|
.card {
|
|
11
20
|
|
|
12
21
|
background-color: var(--cBg);
|
|
13
|
-
padding: @
|
|
22
|
+
padding: @cardPadding;
|
|
23
|
+
|
|
24
|
+
&.row {
|
|
25
|
+
padding: @cardPadding @cardPaddingLong;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&.col {
|
|
29
|
+
padding: @cardPaddingLong @cardPadding;
|
|
30
|
+
}
|
|
14
31
|
|
|
15
32
|
&.bg {
|
|
16
33
|
--cBg: difference(@cBgPage, #0a0a0a);
|
|
@@ -43,7 +60,7 @@
|
|
|
43
60
|
----------------------------------*/
|
|
44
61
|
|
|
45
62
|
&.menu {
|
|
46
|
-
padding: @
|
|
63
|
+
padding: @cardPaddingLong;
|
|
47
64
|
}
|
|
48
65
|
|
|
49
66
|
/*----------------------------------
|
|
@@ -59,25 +76,28 @@
|
|
|
59
76
|
|
|
60
77
|
> .cov-t {
|
|
61
78
|
|
|
62
|
-
margin-top:
|
|
79
|
+
margin-top: -1 * @spacing;
|
|
63
80
|
}
|
|
64
81
|
|
|
65
|
-
> .cover
|
|
66
|
-
> .table {
|
|
82
|
+
&.col > .cover {
|
|
67
83
|
|
|
68
|
-
margin-left:
|
|
69
|
-
margin-right:
|
|
84
|
+
margin-left: -1 * @cardPadding;
|
|
85
|
+
margin-right: -1 * @cardPadding;
|
|
86
|
+
padding-left: @cardPadding;
|
|
87
|
+
padding-right: @cardPadding;
|
|
70
88
|
|
|
71
89
|
&:first-child {
|
|
72
90
|
border-top-left-radius: @radius;
|
|
73
91
|
border-top-right-radius: @radius;
|
|
74
|
-
margin-top:
|
|
92
|
+
margin-top: -1 * @cardPaddingLong;
|
|
93
|
+
padding-top: @cardPaddingLong;
|
|
75
94
|
}
|
|
76
95
|
|
|
77
96
|
&:last-child {
|
|
78
97
|
border-bottom-left-radius: @radius;
|
|
79
98
|
border-bottom-right-radius: @radius;
|
|
80
|
-
margin-bottom:
|
|
99
|
+
margin-bottom: -1 * @cardPaddingLong;
|
|
100
|
+
padding-bottom: @cardPaddingLong;
|
|
81
101
|
}
|
|
82
102
|
}
|
|
83
103
|
|
|
@@ -90,23 +110,23 @@
|
|
|
90
110
|
|
|
91
111
|
.msg, .card.bg.info {
|
|
92
112
|
|
|
93
|
-
padding: @spacing @
|
|
113
|
+
padding: @spacing @cardPaddingLong;
|
|
94
114
|
|
|
95
|
-
.build-theme( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
115
|
+
.build-theme-bg( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
96
116
|
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
.msg, .card.bg {
|
|
100
120
|
&.error {
|
|
101
|
-
.build-theme( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
121
|
+
.build-theme-bg( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
102
122
|
}
|
|
103
123
|
|
|
104
124
|
&.warn {
|
|
105
|
-
.build-theme( lighten(@cWarn, 25%), darken(@cWarn, 30%));
|
|
125
|
+
.build-theme-bg( lighten(@cWarn, 25%), darken(@cWarn, 30%));
|
|
106
126
|
}
|
|
107
127
|
|
|
108
128
|
&.success {
|
|
109
|
-
.build-theme( lighten(@cSuccess, 50%), darken(@cSuccess, 30%));
|
|
129
|
+
.build-theme-bg( lighten(@cSuccess, 50%), darken(@cSuccess, 30%));
|
|
110
130
|
}
|
|
111
131
|
}
|
|
112
132
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
.card,
|
|
2
2
|
.input.text,
|
|
3
3
|
.btn,
|
|
4
|
+
.table,
|
|
4
5
|
i.solid {
|
|
5
6
|
|
|
6
|
-
.build-theme( #fff, #8E8E8E);
|
|
7
|
+
.build-theme-bg( #fff, #8E8E8E);
|
|
7
8
|
|
|
8
9
|
&:not(.bg) {
|
|
9
10
|
background: white;
|
|
10
|
-
box-shadow: 0
|
|
11
|
+
box-shadow: 0 3px 2px fade(#000, 10%);
|
|
11
12
|
border: solid 1px fade(#000, 10%);
|
|
12
13
|
border-radius: @radius;
|
|
13
14
|
}
|
|
@@ -18,6 +19,7 @@ i.solid {
|
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
//.card.clickable:hover,
|
|
21
23
|
.btn:hover,
|
|
22
24
|
.input.text.focus {
|
|
23
25
|
z-index: 5;
|
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
@import (reference) "~@/client/assets/theme.less";
|
|
2
2
|
|
|
3
|
+
img.img,
|
|
4
|
+
.bg.img {
|
|
5
|
+
background: @cBgPage - #101010;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.bg.img {
|
|
9
|
+
.build-theme-bg(#000, #fff);
|
|
10
|
+
text-shadow: 0 0 10px fade(#000, 20%);
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
img {
|
|
4
14
|
max-width: 100%;
|
|
5
15
|
display: block;
|
|
6
16
|
|
|
7
17
|
&.img {
|
|
8
18
|
border-radius: @radius;
|
|
9
|
-
background: @cBgPage - #101010;
|
|
10
|
-
object-fit: cover;
|
|
11
|
-
object-position: center;
|
|
12
19
|
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*----------------------------------
|
|
23
|
+
- IMAGE CONFIG
|
|
24
|
+
----------------------------------*/
|
|
25
|
+
|
|
26
|
+
// Default: cover
|
|
27
|
+
.bg.img {
|
|
28
|
+
background-size: cover;
|
|
29
|
+
background-repeat: no-repeat;
|
|
30
|
+
background-position: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
img.img {
|
|
34
|
+
object-fit: cover;
|
|
35
|
+
object-position: center;
|
|
13
36
|
}
|
|
@@ -2,7 +2,6 @@ h1, .h1,
|
|
|
2
2
|
h2,
|
|
3
3
|
h3 {
|
|
4
4
|
|
|
5
|
-
font-family: "Rubik";
|
|
6
5
|
font-weight: 600;
|
|
7
6
|
text-align: inherit;
|
|
8
7
|
color: var(--cTxtImportant);
|
|
@@ -23,6 +22,11 @@ h3 {
|
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
|
|
25
|
+
h1,
|
|
26
|
+
h2 {
|
|
27
|
+
font-family: "Rubik";
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
// sans input.h1, .h1 seul ne peut pas override le style par défaut des champs
|
|
27
31
|
h1, .h1 {
|
|
28
32
|
font-size: @h1Size;
|
|
@@ -37,5 +41,5 @@ h2, .h2 {
|
|
|
37
41
|
h3,
|
|
38
42
|
fieldset > legend {
|
|
39
43
|
font-size: @h3Size;
|
|
40
|
-
line-height:
|
|
44
|
+
line-height: 1.5em;
|
|
41
45
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@bgDelta: #111;
|
|
2
2
|
@fgDelta: #999;
|
|
3
3
|
|
|
4
|
-
.build-theme(
|
|
4
|
+
.build-theme-bg(
|
|
5
5
|
@bg,
|
|
6
6
|
@fg: if( lightness(@bg) >= 80%, @bg - @fgDelta, @bg + @fgDelta),
|
|
7
7
|
@cAccent: @c1,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
// Background
|
|
18
18
|
// TODO: Nettoyer
|
|
19
|
-
@bg2: @bg
|
|
19
|
+
@bg2: darken(@bg, 8%);
|
|
20
20
|
@bgDark: darken(@bg, 5%);
|
|
21
21
|
@bgDarkPlus: darken(@bg, 10%);
|
|
22
22
|
--cBg: @bg;
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
--cLine2: @cLine2;
|
|
37
37
|
|
|
38
38
|
// Text
|
|
39
|
-
.build-theme-
|
|
39
|
+
.build-theme-fg(@fg, @bg, @apply);
|
|
40
40
|
|
|
41
41
|
// Childrens
|
|
42
42
|
& when (@apply = true) {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
.build-theme-
|
|
54
|
+
.build-theme-fg( @cTxtBase, @bg: @cBgPage, @apply: true ) {
|
|
55
55
|
|
|
56
56
|
@isLight: boolean( lightness(@bg) >= 70% );
|
|
57
57
|
|
|
@@ -66,4 +66,6 @@
|
|
|
66
66
|
--cTxtBase: @cTxtBase;
|
|
67
67
|
--cTxtImportant: @cTxtImportant;
|
|
68
68
|
--cTxtAccent: @cTxtAccent;
|
|
69
|
+
|
|
70
|
+
color: var(--cTxtBase);
|
|
69
71
|
}
|
|
File without changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
// Core components
|
|
10
|
+
import Button from '@client/components/button';
|
|
11
|
+
import { Link } from '@client/router';
|
|
12
|
+
|
|
13
|
+
// Resources
|
|
14
|
+
import './index.less';
|
|
15
|
+
|
|
16
|
+
/*----------------------------------
|
|
17
|
+
- TYPE
|
|
18
|
+
----------------------------------*/
|
|
19
|
+
|
|
20
|
+
type TMeta = {
|
|
21
|
+
label: ComponentChild,
|
|
22
|
+
class?: string,
|
|
23
|
+
value: ComponentChild,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type Props = {
|
|
27
|
+
title: string,
|
|
28
|
+
link?: string,
|
|
29
|
+
cover?: {
|
|
30
|
+
color?: string,
|
|
31
|
+
title?: string,
|
|
32
|
+
logo?: string
|
|
33
|
+
},
|
|
34
|
+
metas: TMeta[],
|
|
35
|
+
class?: string,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/*----------------------------------
|
|
39
|
+
- COMPONENT
|
|
40
|
+
----------------------------------*/
|
|
41
|
+
export default ({ title, link, cover, metas, class: className = '' }: Props) => {
|
|
42
|
+
|
|
43
|
+
if (link)
|
|
44
|
+
className += ' clickable';
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
|
|
48
|
+
<article class={"card col " + className}>
|
|
49
|
+
|
|
50
|
+
{cover && (
|
|
51
|
+
<header class="bg img row al-left cover pdb-1" style={{
|
|
52
|
+
backgroundColor: cover.color
|
|
53
|
+
}}>
|
|
54
|
+
|
|
55
|
+
{cover?.logo}
|
|
56
|
+
|
|
57
|
+
{cover.title && (
|
|
58
|
+
<strong>
|
|
59
|
+
{cover?.title}
|
|
60
|
+
</strong>
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
</header>
|
|
64
|
+
)}
|
|
65
|
+
|
|
66
|
+
{link ? (
|
|
67
|
+
<Link to={link} class="txt-left super">
|
|
68
|
+
<h3>{title}</h3>
|
|
69
|
+
</Link>
|
|
70
|
+
) : (
|
|
71
|
+
<h3>{title}</h3>
|
|
72
|
+
)}
|
|
73
|
+
|
|
74
|
+
{metas && (
|
|
75
|
+
<ul class="row fill">
|
|
76
|
+
{metas.map(({ label, value, class: className }) => (
|
|
77
|
+
<li class={"col al-left sp-05"}>
|
|
78
|
+
{label}
|
|
79
|
+
<strong class={className}>{value}</strong>
|
|
80
|
+
</li>
|
|
81
|
+
))}
|
|
82
|
+
</ul>
|
|
83
|
+
)}
|
|
84
|
+
|
|
85
|
+
</article>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@import (reference) "~@/client/assets/theme.less";
|
|
2
|
+
|
|
3
|
+
@hideeWidth: 10em;
|
|
4
|
+
|
|
5
|
+
.scrollable-row {
|
|
6
|
+
|
|
7
|
+
position: relative;
|
|
8
|
+
|
|
9
|
+
> .container {
|
|
10
|
+
padding: @spacing 0;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
position: relative;
|
|
13
|
+
left: 0;
|
|
14
|
+
|
|
15
|
+
> .row {
|
|
16
|
+
justify-content: flex-start;
|
|
17
|
+
padding: 0 @spacing;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
> .btn {
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 50%;
|
|
24
|
+
margin-top: 0 - (@sizeComponent / 2);
|
|
25
|
+
z-index: 1;
|
|
26
|
+
|
|
27
|
+
&.left {
|
|
28
|
+
left: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&.right {
|
|
32
|
+
right: 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&::before,
|
|
37
|
+
&::after {
|
|
38
|
+
content: ' ';
|
|
39
|
+
display: block;
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 0;
|
|
42
|
+
bottom: 0;
|
|
43
|
+
width: @hideeWidth;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&::before {
|
|
47
|
+
left: 0;
|
|
48
|
+
background: linear-gradient(to right, fade(@cBgPage, 100%), fade(@cBgPage, 0%));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&::after {
|
|
52
|
+
background: linear-gradient(to left, fade(@cBgPage, 100%), fade(@cBgPage, 0%));
|
|
53
|
+
right: 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&.stopLeft {
|
|
57
|
+
> .btn.left { display: none; }
|
|
58
|
+
&::before { display: none; }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&.stopRight {
|
|
62
|
+
> .btn.right { display: none; }
|
|
63
|
+
&::after { display: none; }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
// Core components
|
|
10
|
+
import Button from '@client/components/button';
|
|
11
|
+
|
|
12
|
+
// Resources
|
|
13
|
+
import './index.less';
|
|
14
|
+
|
|
15
|
+
/*----------------------------------
|
|
16
|
+
- TYPE
|
|
17
|
+
----------------------------------*/
|
|
18
|
+
|
|
19
|
+
export type Props = {
|
|
20
|
+
children: ComponentChild
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*----------------------------------
|
|
24
|
+
- COMPONENT
|
|
25
|
+
----------------------------------*/
|
|
26
|
+
export default ({ children }: Props) => {
|
|
27
|
+
|
|
28
|
+
const containerRef = React.useRef<HTMLDivElement>();
|
|
29
|
+
const [leftPos, setLeftPos] = React.useState<number>(0);
|
|
30
|
+
|
|
31
|
+
const moveTo = (sens: number) => {
|
|
32
|
+
|
|
33
|
+
const container = containerRef.current;
|
|
34
|
+
if (container === null)
|
|
35
|
+
return console.error(`Unable to scroll: container not defined`);
|
|
36
|
+
|
|
37
|
+
const row = container.children[0];
|
|
38
|
+
if (!row)
|
|
39
|
+
return console.error(`No row found`);
|
|
40
|
+
|
|
41
|
+
const containerWidth = container.getBoundingClientRect().width;
|
|
42
|
+
const rowWidth = row.getBoundingClientRect().width;
|
|
43
|
+
|
|
44
|
+
console.log({ containerWidth, rowWidth });
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
|
|
50
|
+
// If row oveflow, show horizontal arroxs
|
|
51
|
+
console.log({ containerRef });
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div class="scrollable-row stopLeft">
|
|
58
|
+
|
|
59
|
+
<Button class="left" shape="pill" icon="arrow-left" onClick={() => moveTo(-1)} />
|
|
60
|
+
|
|
61
|
+
<div class="container" ref={containerRef}>
|
|
62
|
+
<div class="row" style={{ left: leftPos + 'px' }}>
|
|
63
|
+
{children}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<Button class="right" shape="pill" icon="arrow-right" onClick={() => moveTo(1)} />
|
|
68
|
+
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
}
|
|
@@ -16,18 +16,19 @@ import Dropdown from '@client/components/dropdown.old';
|
|
|
16
16
|
|
|
17
17
|
export type TDonneeInconnue = {[cle: string]: any};
|
|
18
18
|
|
|
19
|
-
export type Props<
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
export type Props<TRow> = {
|
|
20
|
+
|
|
21
|
+
data: TRow[],
|
|
22
|
+
columns: (row: TRow, rows: TRow[], index: number) => TColumn[];
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
setData?: (rows: TRow[]) => void,
|
|
24
25
|
vide?: ComponentChild,
|
|
25
26
|
className?: string,
|
|
26
27
|
|
|
27
|
-
actions?: TAction<
|
|
28
|
+
actions?: TAction<TRow>[]
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
export type
|
|
31
|
+
export type TColumn = {
|
|
31
32
|
label: ComponentChild,
|
|
32
33
|
cell: ComponentChild,
|
|
33
34
|
raw?: number | string | boolean,
|
|
@@ -37,33 +38,33 @@ export type TColonne = {
|
|
|
37
38
|
/*----------------------------------
|
|
38
39
|
- COMPOSANTS
|
|
39
40
|
----------------------------------*/
|
|
40
|
-
export default function Liste<
|
|
41
|
-
data,
|
|
41
|
+
export default function Liste<TRow extends TDonneeInconnue>({
|
|
42
|
+
data: rows, setData, vide ,
|
|
42
43
|
columns, actions, ...props
|
|
43
|
-
}: Props<
|
|
44
|
+
}: Props<TRow>) {
|
|
44
45
|
|
|
45
|
-
if (
|
|
46
|
+
if (rows.length === 0)
|
|
46
47
|
return (
|
|
47
48
|
<div class="card pd-2 col al-center">
|
|
48
49
|
<i src="meh-rolling-eyes" class="xl" />
|
|
49
|
-
Uh ... No
|
|
50
|
+
Uh ... No rows here.
|
|
50
51
|
</div>
|
|
51
52
|
);
|
|
52
53
|
|
|
53
54
|
const [selection, setSelection] = React.useState<number[]>([]);
|
|
54
55
|
const [sort, setSort] = React.useState<{ col: number, dir: 1 | -1 } | null>(null);
|
|
55
56
|
|
|
56
|
-
const trier = (colonne:
|
|
57
|
+
const trier = (colonne: TColumn, iColonne: number) => {
|
|
57
58
|
|
|
58
|
-
if (!
|
|
59
|
-
|
|
59
|
+
if (!setData)
|
|
60
|
+
return console.warn(`[ui][table] Please specify a setData function to enable sorting features.`);
|
|
60
61
|
|
|
61
62
|
const ordre = sort && iColonne === sort.col
|
|
62
63
|
? -1 * sort.dir as (1 | -1) // Inversement ordre
|
|
63
64
|
: 1;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
...
|
|
66
|
+
setData([
|
|
67
|
+
...rows.sort((a: TRow, b: TRow) => {
|
|
67
68
|
|
|
68
69
|
const valA = colonne.valeur(a);
|
|
69
70
|
const valB = colonne.valeur(b);
|
|
@@ -94,7 +95,7 @@ export default function Liste<TDonnee extends TDonneeInconnue>({
|
|
|
94
95
|
----------------------------------*/
|
|
95
96
|
let renduColonnes: ComponentChild[] = [];
|
|
96
97
|
|
|
97
|
-
const renduLignes =
|
|
98
|
+
const renduLignes = rows.map((row: TRow, iDonnee: number) => (
|
|
98
99
|
<tr>
|
|
99
100
|
{/*selectionMultiple && (
|
|
100
101
|
<td>
|
|
@@ -113,7 +114,7 @@ export default function Liste<TDonnee extends TDonneeInconnue>({
|
|
|
113
114
|
</td>
|
|
114
115
|
)*/}
|
|
115
116
|
|
|
116
|
-
{columns(
|
|
117
|
+
{columns(row, rows, iDonnee).map((colonne, iColonne) => {
|
|
117
118
|
|
|
118
119
|
const triable = colonne.raw !== undefined;
|
|
119
120
|
|
|
@@ -141,7 +142,7 @@ export default function Liste<TDonnee extends TDonneeInconnue>({
|
|
|
141
142
|
|
|
142
143
|
{/*actions !== undefined && (
|
|
143
144
|
<td>
|
|
144
|
-
<Popover menu={{ actions,
|
|
145
|
+
<Popover menu={{ actions, rows: row }}>
|
|
145
146
|
<Button taille="s" icone="solid/ellipsis-h" />
|
|
146
147
|
</Popover>
|
|
147
148
|
</td>
|
|
@@ -168,9 +169,9 @@ export default function Liste<TDonnee extends TDonneeInconnue>({
|
|
|
168
169
|
<Checkbox
|
|
169
170
|
nom="toutSelectionner"
|
|
170
171
|
label={false}
|
|
171
|
-
valeur={selection.length >=
|
|
172
|
+
valeur={selection.length >= rows.length}
|
|
172
173
|
onChange={(status: boolean) => {
|
|
173
|
-
setSelection(status ? Object.keys(
|
|
174
|
+
setSelection(status ? Object.keys(rows) : []);
|
|
174
175
|
}}
|
|
175
176
|
/>
|
|
176
177
|
</th>
|
|
@@ -193,18 +194,18 @@ export default function Liste<TDonnee extends TDonneeInconnue>({
|
|
|
193
194
|
<div className="card pdv-05 row inline pos_bottom">
|
|
194
195
|
<strong>{selection.length} selected items</strong>
|
|
195
196
|
|
|
196
|
-
{actions.map((action: TAction<
|
|
197
|
+
{actions.map((action: TAction<TRow>) => {
|
|
197
198
|
|
|
198
199
|
if (!action.multi)
|
|
199
200
|
return;
|
|
200
201
|
|
|
201
|
-
const donneesSelection = selection.map((index: number) =>
|
|
202
|
+
const donneesSelection = selection.map((index: number) => rows[index]);
|
|
202
203
|
|
|
203
204
|
return (
|
|
204
205
|
<Button
|
|
205
206
|
{...(action.bouton ? (action.multi
|
|
206
|
-
? action.bouton([
|
|
207
|
-
: action.bouton(
|
|
207
|
+
? action.bouton([row], [iDonnee])
|
|
208
|
+
: action.bouton(row, iDonnee)
|
|
208
209
|
) : {})}
|
|
209
210
|
icone={action.icone}
|
|
210
211
|
onClick={() => action.onClick && action.onClick(donneesSelection, selection)}
|
|
@@ -107,7 +107,7 @@ route.get('/invite', async ({ auth, schema }) => {
|
|
|
107
107
|
meet,
|
|
108
108
|
activity
|
|
109
109
|
FROM User u
|
|
110
|
-
WHERE referrer = ${user.
|
|
110
|
+
WHERE referrer = ${user.email}
|
|
111
111
|
`.all();
|
|
112
112
|
|
|
113
113
|
const stats = await getStats('UserStats', [
|
|
@@ -118,9 +118,9 @@ route.get('/invite', async ({ auth, schema }) => {
|
|
|
118
118
|
relative: true,
|
|
119
119
|
period: '12 hours',
|
|
120
120
|
interval: '1 hour',
|
|
121
|
-
where: user ? (`user = ` + app.services.sql.esc(user.
|
|
121
|
+
where: user ? (`user = ` + app.services.sql.esc(user.email)) : '0',
|
|
122
122
|
cache: user ? {
|
|
123
|
-
id: 'user.' + user.
|
|
123
|
+
id: 'user.' + user.email + '.referrals'
|
|
124
124
|
} : undefined
|
|
125
125
|
});
|
|
126
126
|
|