5htp 0.3.5 → 0.3.8

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 (102) hide show
  1. package/package.json +4 -3
  2. package/skeleton/docker-compose.yml +7 -15
  3. package/skeleton/identity.yaml +12 -8
  4. package/skeleton/package.json +25 -7
  5. package/skeleton/src/client/assets/identity/logo.svg +13 -63
  6. package/skeleton/src/client/assets/identity/logoAndText.svg +9 -104
  7. package/skeleton/src/client/assets/identity/logoAndTextBlack.svg +11 -0
  8. package/skeleton/src/client/assets/illustration/landing/banner.webp +0 -0
  9. package/skeleton/src/client/assets/illustration/landing/candidate/employers.webp +0 -0
  10. package/skeleton/src/client/assets/illustration/landing/candidate/hero.webp +0 -0
  11. package/skeleton/src/client/assets/illustration/landing/candidate/mentors.webp +0 -0
  12. package/skeleton/src/client/assets/illustration/landing/headhunter/hero.webp +0 -0
  13. package/skeleton/src/client/assets/illustration/landing/hero.jpeg +0 -0
  14. package/skeleton/src/client/assets/illustration/landing/hero.webp +0 -0
  15. package/skeleton/src/client/assets/illustration/landing/hero.xcf +0 -0
  16. package/skeleton/src/client/assets/illustration/landing/recruiter/onboarding.webp +0 -0
  17. package/skeleton/src/client/assets/illustration/landing/team/andre.png +0 -0
  18. package/skeleton/src/client/assets/illustration/landing/team/emma.png +0 -0
  19. package/skeleton/src/client/assets/illustration/landing/team/fei.png +0 -0
  20. package/skeleton/src/client/assets/illustration/landing/team/gaetan.png +0 -0
  21. package/skeleton/src/client/assets/illustration/landing/team/jordan.png +0 -0
  22. package/skeleton/src/client/assets/illustration/landing/team/lery.png +0 -0
  23. package/skeleton/src/client/assets/illustration/landing/team/mehdi.png +0 -0
  24. package/skeleton/src/client/assets/illustration/landing/team/omkar.png +0 -0
  25. package/skeleton/src/client/assets/illustration/landing/team/thibaut.png +0 -0
  26. package/skeleton/src/client/assets/img/background/header-blur.png +0 -0
  27. package/skeleton/src/client/assets/img/partners/citron.svg +987 -0
  28. package/skeleton/src/client/assets/patterns/dots.png +0 -0
  29. package/skeleton/src/client/assets/theme.less +179 -226
  30. package/skeleton/src/client/assets/vars.less +54 -0
  31. package/skeleton/src/client/context.ts +23 -0
  32. package/skeleton/src/client/index.ts +59 -0
  33. package/skeleton/src/client/pages/_messages/400.tsx +45 -0
  34. package/skeleton/src/client/pages/_messages/401.tsx +39 -0
  35. package/skeleton/src/client/pages/_messages/403.tsx +43 -0
  36. package/skeleton/src/client/pages/_messages/404.tsx +42 -0
  37. package/skeleton/src/client/pages/_messages/500.tsx +42 -0
  38. package/skeleton/src/client/pages/platform/Header.less +12 -0
  39. package/skeleton/src/client/pages/platform/Header.tsx +119 -0
  40. package/skeleton/src/client/pages/platform/_layout/index.less +118 -0
  41. package/skeleton/src/client/pages/platform/_layout/index.tsx +131 -0
  42. package/skeleton/src/client/pages/platform/_layout/mobile.less +114 -0
  43. package/skeleton/src/client/pages/platform/_page.tsx +54 -0
  44. package/skeleton/src/client/pages/platform/headhunters/index.tsx +88 -0
  45. package/skeleton/src/client/pages/platform/index.tsx +58 -0
  46. package/skeleton/src/client/pages/platform/missions/index.tsx +149 -0
  47. package/skeleton/src/client/services/metrics/index.ts +59 -0
  48. package/skeleton/src/client/tsconfig.json +4 -1
  49. package/skeleton/src/common/config/router.ts +16 -0
  50. package/skeleton/src/common/forms/company/bookCall.ts +25 -0
  51. package/skeleton/src/common/forms/company/importJob.ts +26 -0
  52. package/skeleton/src/common/forms/company/signup.ts +31 -0
  53. package/skeleton/src/common/forms/headhunter/feedback.ts +31 -0
  54. package/skeleton/src/common/forms/headhunter/mission/cancel.ts +26 -0
  55. package/skeleton/src/common/forms/headhunter/mission/candidate/availability.ts +31 -0
  56. package/skeleton/src/common/forms/headhunter/mission/candidate/education.ts +19 -0
  57. package/skeleton/src/common/forms/headhunter/mission/candidate/identity.ts +31 -0
  58. package/skeleton/src/common/forms/headhunter/mission/candidate/others.ts +19 -0
  59. package/skeleton/src/common/forms/headhunter/mission/candidate/skills.ts +21 -0
  60. package/skeleton/src/common/forms/headhunter/mission/reject.ts +23 -0
  61. package/skeleton/src/common/forms/headhunter/mission/search.ts +78 -0
  62. package/skeleton/src/common/forms/headhunter/signup.ts +34 -0
  63. package/skeleton/src/common/libs/headhunter/candidate/index.ts +155 -0
  64. package/skeleton/src/common/libs/headhunter/mission/index.ts +30 -0
  65. package/skeleton/src/common/libs/hub/index.ts +41 -0
  66. package/skeleton/src/server/config/communication.ts +48 -0
  67. package/skeleton/src/server/config/crosspath.ts +9 -0
  68. package/skeleton/src/server/config/data.ts +34 -0
  69. package/skeleton/src/server/config/database.ts +26 -0
  70. package/skeleton/src/server/config/internal.ts +21 -0
  71. package/skeleton/src/server/config/user.ts +90 -0
  72. package/skeleton/src/server/index.ts +111 -23
  73. package/skeleton/src/server/libs/utils/slug.ts +11 -0
  74. package/skeleton/src/server/routes/global.ts +33 -0
  75. package/skeleton/src/server/routes/headhunters.ts +24 -0
  76. package/skeleton/src/server/routes/missions.ts +50 -0
  77. package/skeleton/src/server/services/Headhunter/index.ts +127 -0
  78. package/skeleton/src/server/services/Headhunter/service.json +6 -0
  79. package/skeleton/src/server/services/Mission/index.ts +174 -0
  80. package/skeleton/src/server/services/Mission/service.json +6 -0
  81. package/skeleton/src/server/services/email/sendgrid/index.ts +97 -0
  82. package/skeleton/src/server/services/email/sendgrid/service.json +6 -0
  83. package/skeleton/src/server/services/slack/index.ts +105 -0
  84. package/skeleton/src/server/services/slack/service.json +6 -0
  85. package/skeleton/src/server/services/users/index.ts +133 -0
  86. package/skeleton/src/server/services/users/service.json +6 -0
  87. package/skeleton/src/server/tsconfig.json +6 -8
  88. package/skeleton/var/typings/routes.d.ts +541 -0
  89. package/src/compiler/common/babel/index.ts +28 -25
  90. package/src/index.ts +1 -1
  91. package/src/utils/keyboard.ts +1 -1
  92. package/skeleton/package-lock.json +0 -6139
  93. package/skeleton/src/client/components/LoginModal.tsx +0 -45
  94. package/skeleton/src/client/pages/app/_layout/index.less +0 -20
  95. package/skeleton/src/client/pages/app/_layout/index.tsx +0 -33
  96. package/skeleton/src/client/pages/app/index.tsx +0 -57
  97. package/skeleton/src/client/pages/landing/_layout/index.less +0 -145
  98. package/skeleton/src/client/pages/landing/_layout/index.tsx +0 -63
  99. package/skeleton/src/client/pages/landing/index.tsx +0 -73
  100. package/skeleton/src/server/models.ts +0 -117
  101. package/skeleton/src/server/routes/general.ts +0 -66
  102. package/skeleton/src/server/services/auth/index.ts +0 -80
@@ -0,0 +1,43 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+
8
+ // Core
9
+ import { Router } from '@app';
10
+ import { Button } from '@client/components';
11
+
12
+ // App
13
+ import useHeader from '@client/pages/useHeader';
14
+
15
+ /*----------------------------------
16
+ - CONTROLEUR
17
+ ----------------------------------*/
18
+ Router.error( 403, {}, ({ data }) => {
19
+
20
+ useHeader({
21
+ title: 'Access Denied.',
22
+ subtitle: data.message
23
+ });
24
+
25
+ return (
26
+ <div class="card w-3-4 col pd-2">
27
+
28
+ <div class="col al-center">
29
+
30
+ <i src="times-circle" class="fg error xxl" />
31
+
32
+ <h1>Access Denied.</h1>
33
+
34
+ <p>{data.message}</p>
35
+
36
+ </div>
37
+
38
+ <Button type="primary" link="https://crosspathworkspace.slack.com/archives/C04L2TGR5J6">
39
+ Report to the dev team
40
+ </Button>
41
+ </div>
42
+ )
43
+ });
@@ -0,0 +1,42 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+
8
+ // Core
9
+ import { Router } from '@app';
10
+ import { Button } from '@client/components';
11
+
12
+ // App
13
+ import useHeader from '@client/pages/useHeader';
14
+
15
+ /*----------------------------------
16
+ - CONTROLEUR
17
+ ----------------------------------*/
18
+ Router.error( 404, {}, ({ data }) => {
19
+
20
+ useHeader({
21
+ title: 'Page Not Found',
22
+ subtitle: data.message
23
+ });
24
+
25
+ return (
26
+ <div class="card w-3-4 col pd-2">
27
+
28
+ <div class="col al-center">
29
+
30
+ <i src="times-circle" class="fg error xxl" />
31
+
32
+ <h1>Page Not Found</h1>
33
+
34
+ <p>{data.message}</p>
35
+ </div>
36
+
37
+ <Button type="primary" link="https://crosspathworkspace.slack.com/archives/C04L2TGR5J6">
38
+ Report to the dev team
39
+ </Button>
40
+ </div>
41
+ )
42
+ });
@@ -0,0 +1,42 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+
8
+ // Core
9
+ import { Router } from '@app';
10
+ import { Button } from '@client/components';
11
+
12
+ // App
13
+ import useHeader from '@client/pages/useHeader';
14
+
15
+ /*----------------------------------
16
+ - CONTROLEUR
17
+ ----------------------------------*/
18
+ Router.error( 500, {}, ({ data }) => {
19
+
20
+ useHeader({
21
+ title: 'Technical Error',
22
+ subtitle: data.message
23
+ });
24
+
25
+ return (
26
+ <div class="card w-3-4 col pd-2">
27
+
28
+ <div class="col al-center">
29
+
30
+ <i src="times-circle" class="fg error xxl" />
31
+
32
+ <h1>Technical Error</h1>
33
+
34
+ <p>{data.message}</p>
35
+ </div>
36
+
37
+ <Button type="primary" link="https://crosspathworkspace.slack.com/archives/C04L2TGR5J6">
38
+ Report to the dev team
39
+ </Button>
40
+ </div>
41
+ )
42
+ });
@@ -0,0 +1,12 @@
1
+ header.entityHeader {
2
+
3
+ /*main > &:first-child {
4
+ margin-top: -@spacing;
5
+ }*/
6
+
7
+ i.logo {
8
+ margin-bottom: -3em;
9
+ position: absolute;
10
+ }
11
+
12
+ }
@@ -0,0 +1,119 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+ import type { ComponentChild } from 'preact';
8
+
9
+ // Core
10
+ import { Logo, Button } from '@client/components';
11
+ import useContext from '@/client/context';
12
+
13
+ // Resources
14
+ import './Header.less';
15
+ import LogoImg from '@/client/assets/identity/logo.svg';
16
+
17
+ /*----------------------------------
18
+ - TYPES
19
+ ----------------------------------*/
20
+ type TMeta = {
21
+ label: ComponentChild,
22
+ class?: string,
23
+ value: ComponentChild,
24
+ }
25
+
26
+ export type Props = {
27
+ title: ComponentChild,
28
+ logo?: ComponentChild
29
+ image?: string,
30
+ color?: string,
31
+ entity?: string,
32
+
33
+ align?: 'center' | 'bottom',
34
+
35
+ metas?: TMeta[],
36
+ class?: string,
37
+ children?: ComponentChild
38
+ }
39
+
40
+ /*----------------------------------
41
+ - COMPONENT
42
+ ----------------------------------*/
43
+ export default function Header({
44
+ title, logo, image, color, entity,
45
+ align, children,
46
+ metas, class: className
47
+ }: Props) {
48
+
49
+ const context = useContext();
50
+
51
+ return (
52
+ <header class={
53
+ "entityHeader card pd-05 bg img col h-1-a sp-0 " +
54
+ (color ? 'colorize' : 'blur') +
55
+ ' ' + (className || '')
56
+ } style={{
57
+ backgroundColor: '#' + (color || 'efefef'),
58
+ backgroundImage: image
59
+ ? 'url(' + image + ')'
60
+ : undefined
61
+ }}>
62
+
63
+ <div id="mobileBtns" class="row sp-btw">
64
+
65
+ <Button icon="bars" size="s" id='navMenuBtn' shape='icon'
66
+ onClick={() => context.setOpenMenu('navig')} />
67
+
68
+ <img class="logo l" src={LogoImg} />
69
+
70
+ <Button icon="user" size="s" id='userMenuBtn' shape='icon'
71
+ onClick={() => context.setOpenMenu('user')} />
72
+ </div>
73
+
74
+ {children ? (
75
+ <div class="col row-1 pdh-1 pdb-2">
76
+
77
+ {children}
78
+
79
+ </div>
80
+ ) : (
81
+ <div class="row row-1 pdh-1 pdb-2">
82
+
83
+ <h1>{title}</h1>
84
+
85
+ </div>
86
+ )}
87
+
88
+ {/*logo ? (
89
+ <div class="entity row">
90
+ {typeof logo === 'string'
91
+ ? <Logo src={logo} size="xl" />
92
+ : logo}
93
+
94
+ {entity && (
95
+ <strong class="coverTitle">
96
+ {entity}
97
+ </strong>
98
+ )}
99
+
100
+ <h1 class="mainTitle">{title}</h1>
101
+ </div>
102
+ ) : (
103
+ <h1 class="mainTitle row-1">{title}</h1>
104
+ )*/}
105
+
106
+ {metas && (
107
+ <ul class="row fill al-top">
108
+ {metas.map(({ label, value, class: className }) => (
109
+ <li class={"col al-left txt-left sp-05"}>
110
+ {label}
111
+ <strong class={className}>{value}</strong>
112
+ </li>
113
+ ))}
114
+ </ul>
115
+ )}
116
+
117
+ </header>
118
+ )
119
+ }
@@ -0,0 +1,118 @@
1
+ @import (reference) "@/client/assets/vars.less";
2
+
3
+ #layout.dashboard {
4
+
5
+ /*----------------------------------
6
+ - LAYOUT
7
+ ----------------------------------*/
8
+
9
+ > .center {
10
+
11
+ min-height: 100vh;
12
+ max-width: @layoutWidth;
13
+ width: 100%;
14
+ margin: 0 auto;
15
+ gap: 0;
16
+
17
+ > * {
18
+ padding: 0.5em 1em;
19
+ }
20
+ }
21
+
22
+ #sidebar,
23
+ #user {
24
+ > .col {
25
+ position: sticky;
26
+ top: @spacing;
27
+ }
28
+ }
29
+
30
+ #sidebar {
31
+ flex: 0 0 @navigSidebarWidth;
32
+ width: @navigSidebarWidth; // For mobile mode = absolute display
33
+ display: flex;
34
+ border-right: solid 1px #e5e5e5;
35
+
36
+ max-height: 100vh;
37
+ position: sticky;
38
+ top: 0;
39
+
40
+ #userMenuBtn {
41
+ position: absolute;
42
+ top: @spacing;
43
+ right: @spacing;
44
+ z-index: 2;
45
+ }
46
+
47
+ #identity {
48
+
49
+ // Align with the space top menu
50
+ height: @sizeComponent;
51
+
52
+ img.logo {
53
+ flex: 0 0 3em;
54
+ }
55
+ }
56
+ }
57
+
58
+ #page {
59
+ flex: 1;
60
+
61
+ > header {
62
+
63
+ img.logo {
64
+ height: 48px;
65
+ }
66
+
67
+ }
68
+
69
+ > main {
70
+ padding-bottom: 20em;
71
+ }
72
+ }
73
+
74
+ #user {
75
+ flex: 0 0 @userSidebarWidth;
76
+ width: @userSidebarWidth; // For mobile mode = absolute display
77
+ border-left: solid 1px #e5e5e5;
78
+ }
79
+
80
+ .page {
81
+
82
+ display: flex;
83
+ flex-direction: column;
84
+ gap: 2em;
85
+ padding-bottom: 15vh;
86
+
87
+ > * {
88
+ + * {}
89
+ }
90
+ }
91
+
92
+ /*----------------------------------
93
+ - COMPONENT
94
+ ----------------------------------*/
95
+
96
+ h2 {
97
+ text-align: left;
98
+ //color: var(--cTxtDesc);
99
+ }
100
+ }
101
+
102
+ @import "./mobile.less";
103
+
104
+ #loading {
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+
109
+ background: fade(#fff, 50%);
110
+ //backdrop-filter: blur(10px);
111
+ z-index: 998;
112
+
113
+ position: fixed;
114
+ top: 0;
115
+ left: 0;
116
+ width: 100vw;
117
+ height: 100vh
118
+ }
@@ -0,0 +1,131 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+ import type { ComponentChild } from 'preact';
8
+ import { useErrorBoundary } from 'preact/hooks';
9
+
10
+ // Core
11
+ import useContext, { ClientContext } from '@/client/context';
12
+
13
+ // Core components
14
+ import RouterComponent from '@client/services/router/components/router';
15
+ import { Button, Popover } from '@client/components';
16
+
17
+ // Resources
18
+ import "./index.less";
19
+ import Logo from '@/client/assets/identity/logo.svg';
20
+
21
+ /*----------------------------------
22
+ - COMPOSANT
23
+ ----------------------------------*/
24
+ export default function App ({ context, menu }: {
25
+ context: ClientContext,
26
+ menu: ComponentChild
27
+ }) {
28
+
29
+ const { Router, api, user } = context;
30
+
31
+ const [openMenu, setOpenMenu] = React.useState<'user'|'navig'>();
32
+
33
+ const userMenuState = React.useState(false);
34
+
35
+ context.setOpenMenu = setOpenMenu;
36
+
37
+ useErrorBoundary( e => {
38
+ console.error("An error occurred.", e);
39
+ });
40
+
41
+ const logout = () => api.post('/auth/logout').then(() => {
42
+ Router.go('https://becrosspath.com');
43
+ })
44
+
45
+ if (user === null)
46
+ return (
47
+ <div class="row pd-3">
48
+ <div class="card w-3-4 col al-center pd-2">
49
+
50
+ <i src="times-circle" class="fg error xxl" />
51
+
52
+ <h1>Authentication Required</h1>
53
+ </div>
54
+ </div>
55
+ )
56
+
57
+ return (
58
+ <div id="layout" class={"dashboard" + (openMenu ? ' ' + openMenu + 'MenuOpen' : '')}
59
+ onClick={(e) => {
60
+ if (openMenu && e.target?.id === 'page')
61
+ setOpenMenu(null)
62
+ }}>
63
+ <div class="center row al-fill">
64
+
65
+ <header id="sidebar">
66
+
67
+ <div class="col al-fill">
68
+ <div id="identity" class="row">
69
+ <img class="logo l" src={Logo} />
70
+ <div class="col col-1 al-left sp-0">
71
+ <strong>CrossPath</strong>
72
+ CSM ©
73
+ </div>
74
+ </div>
75
+
76
+ <nav class="row-1">
77
+ <ul class="menu col al-top">
78
+ <Button nav="exact" link="/" icon="home-alt">
79
+ Overview
80
+ </Button>
81
+ <Button link="/missions" icon="bullseye">
82
+ Missions
83
+ </Button>
84
+ <Button link="/headhunters" icon="search">
85
+ Headhunters
86
+ </Button>
87
+ <Button link="/clients" icon="dollar-sign">
88
+ Clients <span class="badge s bg info">Soon</span>
89
+ </Button>
90
+ <Button link="/candidates" icon="users">
91
+ Candidates <span class="badge s bg info">Soon</span>
92
+ </Button>
93
+ <Button link="/system" icon="cog">
94
+ System <span class="badge s bg info">Soon</span>
95
+ </Button>
96
+ </ul>
97
+ </nav>
98
+
99
+ <ul class="menu col">
100
+ <li>
101
+ <Button shape="icon" icon="bell" onClick={() => toast.info("This feature is coming soon!")} />
102
+ </li>
103
+ <li>
104
+ <Button shape="icon" icon="comment-alt-lines" onClick={() => toast.info("This feature is coming soon!")} />
105
+ </li>
106
+ <li>
107
+ <Popover state={userMenuState} content={(
108
+ <ul class="col menu">
109
+ <li class="col sp-0 al-left">
110
+ Logged as <strong>{user.name}</strong>
111
+ </li>
112
+ <li>
113
+ <Button icon="power-off" async onClick={logout}>Logout</Button>
114
+ </li>
115
+ </ul>
116
+ )}>
117
+ <i class="logo mgv-1" style={{
118
+ background: 'url(https://recruiters.becrosspath.com/hub/team/' + user.slug + '/photo.webp)'
119
+ }} />
120
+ </Popover>
121
+ </li>
122
+ </ul>
123
+ </div>
124
+
125
+ </header>
126
+
127
+ <RouterComponent service={Router} />
128
+ </div>
129
+ </div>
130
+ )
131
+ }
@@ -0,0 +1,114 @@
1
+ @import (reference) "@/client/assets/vars.less";
2
+
3
+ #layout.dashboard {
4
+
5
+ // Minimize sidebar
6
+ @media only screen and (max-width: 1500px) and (min-width: 600px) {
7
+
8
+ #sidebar {
9
+ flex: 0 0 7em;
10
+
11
+ #identity > img + div {
12
+ display: none;
13
+ }
14
+
15
+ .menu a .label {
16
+ display: none;
17
+ }
18
+
19
+ .card.bg.blur {
20
+ display: none;
21
+ }
22
+ }
23
+ }
24
+
25
+ // Hide mobile display buttons when no mobile mode
26
+ @media only screen and (min-width: 900px) {
27
+ #mobileBtns {
28
+ visibility: hidden;
29
+ }
30
+ }
31
+
32
+ // Enter mobile mode: mobile buttons + slideable page
33
+ @media only screen and (max-width: 900px) {
34
+
35
+ #page {
36
+ z-index: 1;
37
+ background: #F5F5F5;
38
+ transition: transform .2s ease-out;
39
+ }
40
+
41
+ &.userMenuOpen,
42
+ &.navigMenuOpen {
43
+ #page {
44
+ box-shadow: 0 0 40px fade(#000, 20%);
45
+
46
+ &::after {
47
+ content: ' ';
48
+ background: fade(#F5F5F5, 50%);
49
+ backdrop-filter: blur(10px);
50
+ position: fixed;
51
+ top: 0;
52
+ left: 0;
53
+ right: 0;
54
+ bottom: 0;
55
+ z-index: 5;
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ // Autohide user sidebar
62
+ @media only screen and (max-width: 900px) {
63
+
64
+ #user {
65
+ position: fixed;
66
+ z-index: 0;
67
+ top: 0;
68
+ bottom: 0;
69
+ right: 0;
70
+ overflow: auto;
71
+ opacity: 0;
72
+ transition: opacity .2s linear;
73
+ }
74
+
75
+ &.userMenuOpen {
76
+
77
+ #page {
78
+ @userMenuOpenGap: @userSidebarWidth + 2em;
79
+ transform: ~"translateX(-@{userMenuOpenGap})";
80
+ }
81
+
82
+ #user {
83
+ opacity: 1;
84
+ }
85
+ }
86
+ }
87
+
88
+ // Autohide navig sidebar
89
+ @media only screen and (max-width: 600px) {
90
+
91
+ #sidebar {
92
+ position: fixed;
93
+ z-index: 0;
94
+ top: 0;
95
+ bottom: 0;
96
+ left: 0;
97
+ overflow: auto;
98
+ opacity: 0;
99
+ transition: opacity .2s linear;
100
+ }
101
+
102
+ &.navigMenuOpen {
103
+ #page {
104
+ @navigMenuOpenGap: @navigSidebarWidth + 2em;
105
+ transform: ~"translateX(@{navigMenuOpenGap})";
106
+ }
107
+
108
+ #sidebar {
109
+ opacity: 1;
110
+ }
111
+ }
112
+
113
+ }
114
+ }
@@ -0,0 +1,54 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import React from 'react';
7
+ import type { ComponentChild } from 'preact';
8
+ import { useState } from 'preact/hooks';
9
+
10
+ // Core
11
+ import useContext from '@/client/context';
12
+ import { Button, Popover, CircularProgressbar, Logo } from '@client/components';
13
+ import useHeader, { Props as useHeaderProps } from '@client/pages/useHeader';
14
+
15
+ /*----------------------------------
16
+ - TYPES
17
+ ----------------------------------*/
18
+
19
+ export type Props = {
20
+ children: ComponentChild,
21
+ navigation?: ComponentChild,
22
+ sidebar?: ComponentChild
23
+ } & useHeaderProps
24
+
25
+ /*----------------------------------
26
+ - DEPENDANCES
27
+ ----------------------------------*/
28
+ export default ({ children, navigation, sidebar, ...useHeaderProps }: Props) => {
29
+
30
+ /*----------------------------------
31
+ - INIT
32
+ ----------------------------------*/
33
+
34
+ const { user, api, Router, toast, modal } = useContext();
35
+
36
+ useHeader(useHeaderProps);
37
+
38
+ /*----------------------------------
39
+ - ACTIONS
40
+ ----------------------------------*/
41
+
42
+ /*----------------------------------
43
+ - RENDER
44
+ ----------------------------------*/
45
+ return <>
46
+ <div id="page" class="col al-top">
47
+ <main class="col">
48
+
49
+ {children}
50
+
51
+ </main>
52
+ </div>
53
+ </>
54
+ }