crewos 0.1.0

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 (64) hide show
  1. package/app/.env.example +1 -0
  2. package/app/index.html +50 -0
  3. package/app/package.json +25 -0
  4. package/app/public/favicon.svg +1 -0
  5. package/app/public/images/cursor-ide-guiiding.png +0 -0
  6. package/app/public/images/gpt.jpg +0 -0
  7. package/app/src/app.jsx +22 -0
  8. package/app/src/components/ConfirmModal.jsx +50 -0
  9. package/app/src/components/Icons.jsx +377 -0
  10. package/app/src/components/RedirectRoute.jsx +14 -0
  11. package/app/src/components/SplashScreen.jsx +15 -0
  12. package/app/src/hooks/useAuth.js +28 -0
  13. package/app/src/index.css +268 -0
  14. package/app/src/main.jsx +5 -0
  15. package/app/src/navigations/AuthRoutes.jsx +15 -0
  16. package/app/src/navigations/MainRoutes.jsx +15 -0
  17. package/app/src/navigations/OnboardingRoutes.jsx +15 -0
  18. package/app/src/navigations/index.jsx +37 -0
  19. package/app/src/pages/Home/index.jsx +2095 -0
  20. package/app/src/pages/Login/index.jsx +118 -0
  21. package/app/src/pages/Onboarding/index.jsx +550 -0
  22. package/app/src/services/api.js +46 -0
  23. package/app/src/services/auth.service.js +3 -0
  24. package/app/src/services/config.service.js +13 -0
  25. package/app/src/services/member.service.js +7 -0
  26. package/app/src/services/onboarding.service.js +17 -0
  27. package/app/src/services/role.service.js +6 -0
  28. package/app/src/services/task.service.js +22 -0
  29. package/app/src/stores/auth.store.js +7 -0
  30. package/app/src/utils/environments.js +5 -0
  31. package/app/vite.config.js +10 -0
  32. package/app/yarn.lock +1337 -0
  33. package/backend/package-lock.json +918 -0
  34. package/backend/package.json +18 -0
  35. package/backend/src/configs/db.config.js +40 -0
  36. package/backend/src/controllers/auth.controller.js +19 -0
  37. package/backend/src/controllers/config.controller.js +23 -0
  38. package/backend/src/controllers/member.controller.js +30 -0
  39. package/backend/src/controllers/models.controller.js +25 -0
  40. package/backend/src/controllers/onboarding.controller.js +49 -0
  41. package/backend/src/controllers/role.controller.js +17 -0
  42. package/backend/src/controllers/task.controller.js +63 -0
  43. package/backend/src/index.js +36 -0
  44. package/backend/src/middlewares/onboarding.guard.js +14 -0
  45. package/backend/src/routes/auth.route.js +8 -0
  46. package/backend/src/routes/config.route.js +11 -0
  47. package/backend/src/routes/index.js +22 -0
  48. package/backend/src/routes/member.route.js +11 -0
  49. package/backend/src/routes/models.route.js +8 -0
  50. package/backend/src/routes/onboarding.route.js +13 -0
  51. package/backend/src/routes/role.route.js +9 -0
  52. package/backend/src/routes/task.route.js +20 -0
  53. package/backend/src/services/auth.service.js +14 -0
  54. package/backend/src/services/config.service.js +176 -0
  55. package/backend/src/services/data/roles.json +474 -0
  56. package/backend/src/services/member.service.js +77 -0
  57. package/backend/src/services/onboarding.service.js +328 -0
  58. package/backend/src/services/role.service.js +23 -0
  59. package/backend/src/services/task.service.js +665 -0
  60. package/backend/src/utils/catcher.js +9 -0
  61. package/backend/src/utils/sanitize.js +13 -0
  62. package/backend/yarn.lock +513 -0
  63. package/bin/crewos.js +307 -0
  64. package/package.json +11 -0
@@ -0,0 +1,268 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@400;500;600;700&display=swap');
2
+ @import 'tailwindcss';
3
+
4
+ :root {
5
+ --font-sans: 'Barlow Condensed', sans-serif;
6
+
7
+ --space-1: 0.25rem;
8
+ --space-2: 0.5rem;
9
+ --space-3: 0.75rem;
10
+ --space-4: 1rem;
11
+ --space-5: 1.25rem;
12
+ --space-6: 1.5rem;
13
+ --space-8: 2rem;
14
+ --space-10: 2.5rem;
15
+
16
+ --radius-sm: 0;
17
+ --radius-md: 0;
18
+ --radius-lg: 0;
19
+ --radius-xl: 0;
20
+
21
+ --color-bg: #050a07;
22
+ --color-surface: #0b130f;
23
+ --color-surface-soft: #111b15;
24
+ --color-surface-strong: #16231b;
25
+ --color-text: #eef7f0;
26
+ --color-muted: #94a79a;
27
+ --color-border: rgba(181, 243, 106, 0.14);
28
+ --color-primary: #8fdc4f;
29
+ --color-primary-hover: #a8eb69;
30
+ --color-primary-contrast: #08110c;
31
+ --color-accent: #42d662;
32
+ --color-danger: #ff6f7d;
33
+
34
+ --shadow-card: 0 24px 60px -34px rgba(0, 0, 0, 0.75);
35
+ --shadow-soft: 0 14px 34px -24px rgba(0, 0, 0, 0.7);
36
+ }
37
+
38
+ * {
39
+ box-sizing: border-box;
40
+ }
41
+
42
+ html,
43
+ body,
44
+ #app {
45
+ min-height: 100%;
46
+ }
47
+
48
+ body {
49
+ margin: 0;
50
+ font-family: var(--font-sans);
51
+ color: var(--color-text);
52
+ background:
53
+ radial-gradient(circle at 12% 12%, rgba(143, 220, 79, 0.14), transparent 34%),
54
+ radial-gradient(circle at 85% 6%, rgba(66, 214, 98, 0.12), transparent 30%),
55
+ linear-gradient(180deg, rgba(15, 25, 19, 0.92) 0%, rgba(5, 10, 7, 1) 42%),
56
+ var(--color-bg);
57
+ background-attachment: fixed;
58
+ }
59
+
60
+ button,
61
+ input,
62
+ textarea,
63
+ select {
64
+ font: inherit;
65
+ }
66
+
67
+ .ui-page {
68
+ min-height: 100vh;
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ }
73
+
74
+ .ui-card {
75
+ background: color-mix(in oklab, var(--color-surface) 96%, black 4%);
76
+ border: 1px solid var(--color-border);
77
+ border-radius: var(--radius-xl);
78
+ box-shadow: var(--shadow-card);
79
+ backdrop-filter: blur(14px);
80
+ }
81
+
82
+ .ui-panel {
83
+ background: var(--color-surface-soft);
84
+ border: 1px solid color-mix(in oklab, var(--color-border) 92%, transparent 8%);
85
+ border-radius: var(--radius-lg);
86
+ box-shadow: var(--shadow-soft);
87
+ }
88
+
89
+ .ui-label {
90
+ font-size: 0.7rem;
91
+ text-transform: uppercase;
92
+ letter-spacing: 0.18em;
93
+ color: var(--color-muted);
94
+ font-weight: 600;
95
+ }
96
+
97
+ .ui-value {
98
+ margin-top: var(--space-2);
99
+ color: var(--color-text);
100
+ font-size: 1.03rem;
101
+ font-weight: 600;
102
+ line-height: 1.35;
103
+ }
104
+
105
+ .ui-button-primary {
106
+ border: 0;
107
+ border-radius: var(--radius-md);
108
+ padding: var(--space-3) var(--space-5);
109
+ background: linear-gradient(
110
+ 135deg,
111
+ var(--color-primary) 0%,
112
+ color-mix(in oklab, var(--color-primary) 78%, #d8ff8a 22%) 100%
113
+ );
114
+ color: var(--color-primary-contrast);
115
+ display: inline-flex;
116
+ align-items: center;
117
+ gap: var(--space-3);
118
+ font-weight: 600;
119
+ line-height: 1;
120
+ cursor: pointer;
121
+ box-shadow: 0 18px 34px -22px rgba(143, 220, 79, 0.58);
122
+ transition: transform 180ms ease, filter 180ms ease, box-shadow 180ms ease;
123
+ }
124
+
125
+ .ui-button-primary:hover:not(:disabled) {
126
+ transform: translateY(-1px);
127
+ filter: saturate(1.08);
128
+ box-shadow: 0 22px 42px -22px rgba(143, 220, 79, 0.68);
129
+ }
130
+
131
+ .ui-button-primary:disabled {
132
+ opacity: 0.66;
133
+ cursor: not-allowed;
134
+ }
135
+
136
+ .ui-button-secondary {
137
+ border: 1px solid var(--color-border);
138
+ border-radius: var(--radius-md);
139
+ padding: var(--space-3) var(--space-5);
140
+ background: color-mix(in oklab, var(--color-surface) 86%, #142019 14%);
141
+ color: var(--color-text);
142
+ display: inline-flex;
143
+ align-items: center;
144
+ gap: var(--space-3);
145
+ font-weight: 600;
146
+ cursor: pointer;
147
+ transition: transform 180ms ease, border-color 180ms ease;
148
+ }
149
+
150
+ .ui-button-secondary:hover {
151
+ transform: translateY(-1px);
152
+ border-color: color-mix(in oklab, var(--color-primary) 50%, var(--color-border) 50%);
153
+ }
154
+
155
+ .ui-pill-button {
156
+ border: 1px solid var(--color-border);
157
+ border-radius: 999px;
158
+ padding: 0.4rem 0.8rem;
159
+ background: color-mix(in oklab, var(--color-surface-soft) 88%, black 12%);
160
+ color: var(--color-text);
161
+ display: inline-flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ font-size: 0.72rem;
165
+ font-weight: 600;
166
+ letter-spacing: 0.1em;
167
+ text-transform: uppercase;
168
+ cursor: pointer;
169
+ transition: transform 180ms ease, border-color 180ms ease, color 180ms ease;
170
+ }
171
+
172
+ .ui-pill-button:hover {
173
+ transform: translateY(-1px);
174
+ border-color: color-mix(in oklab, var(--color-primary) 50%, var(--color-border) 50%);
175
+ color: var(--color-primary);
176
+ }
177
+
178
+ .ui-button-danger {
179
+ border-color: color-mix(in oklab, var(--color-danger) 50%, var(--color-border) 50%);
180
+ background: color-mix(in oklab, var(--color-danger) 11%, var(--color-surface) 89%);
181
+ color: color-mix(in oklab, var(--color-danger) 88%, white 12%);
182
+ }
183
+
184
+ .ui-button-danger:hover {
185
+ border-color: color-mix(in oklab, var(--color-danger) 70%, var(--color-border) 30%);
186
+ background: color-mix(in oklab, var(--color-danger) 13%, var(--color-surface) 87%);
187
+ }
188
+
189
+ .ui-icon-button {
190
+ width: 2.2rem;
191
+ height: 2.2rem;
192
+ border-radius: var(--radius-md);
193
+ border: 1px solid var(--color-border);
194
+ background: color-mix(in oklab, var(--color-surface) 88%, #142019 12%);
195
+ color: var(--color-text);
196
+ display: inline-flex;
197
+ align-items: center;
198
+ justify-content: center;
199
+ cursor: pointer;
200
+ transition:
201
+ transform 160ms ease,
202
+ border-color 160ms ease,
203
+ box-shadow 160ms ease,
204
+ background-color 160ms ease,
205
+ color 160ms ease;
206
+ }
207
+
208
+ .ui-icon-button:hover {
209
+ transform: translateY(-1px);
210
+ border-color: color-mix(in oklab, var(--color-primary) 40%, var(--color-border) 60%);
211
+ box-shadow: var(--shadow-soft);
212
+ }
213
+
214
+ .ui-icon-button:active {
215
+ transform: translateY(0);
216
+ }
217
+
218
+ .ui-icon-button-danger {
219
+ color: color-mix(in oklab, var(--color-danger) 86%, #4b1010 14%);
220
+ border-color: color-mix(in oklab, var(--color-danger) 45%, var(--color-border) 55%);
221
+ background: color-mix(in oklab, var(--color-danger) 9%, var(--color-surface) 91%);
222
+ }
223
+
224
+ .ui-icon-button-danger:hover {
225
+ border-color: color-mix(in oklab, var(--color-danger) 68%, var(--color-border) 32%);
226
+ }
227
+
228
+ .ui-icon-button-success {
229
+ color: var(--color-primary);
230
+ border-color: color-mix(in oklab, var(--color-primary) 58%, var(--color-border) 42%);
231
+ background: color-mix(in oklab, var(--color-primary) 12%, var(--color-surface) 88%);
232
+ }
233
+
234
+ .ui-number-input {
235
+ -moz-appearance: textfield;
236
+ }
237
+
238
+ .ui-number-input::-webkit-outer-spin-button,
239
+ .ui-number-input::-webkit-inner-spin-button {
240
+ -webkit-appearance: none;
241
+ margin: 0;
242
+ }
243
+
244
+ .ui-fade-in {
245
+ animation: ui-fade-in 280ms ease-out;
246
+ }
247
+
248
+ @keyframes ui-fade-in {
249
+ from {
250
+ opacity: 0;
251
+ transform: translateY(6px);
252
+ }
253
+ to {
254
+ opacity: 1;
255
+ transform: translateY(0);
256
+ }
257
+ }
258
+
259
+ @keyframes flow-pulse {
260
+ 0%, 100% { opacity: 1; transform: scale(1); }
261
+ 50% { opacity: 0.5; transform: scale(0.6); }
262
+ }
263
+
264
+ @keyframes dash-march {
265
+ to {
266
+ stroke-dashoffset: -20;
267
+ }
268
+ }
@@ -0,0 +1,5 @@
1
+ import { render } from 'preact';
2
+ import './index.css';
3
+ import App from './app.jsx';
4
+
5
+ render(<App />, document.getElementById('app'));
@@ -0,0 +1,15 @@
1
+ import { Router, Route } from 'preact-iso';
2
+
3
+ import Login from '../pages/Login';
4
+ import RedirectRoute from '../components/RedirectRoute';
5
+
6
+ const AuthRoutes = () => {
7
+ return (
8
+ <Router>
9
+ <Route path="/login" component={Login} />
10
+ <Route default component={() => <RedirectRoute to="/login" />} />
11
+ </Router>
12
+ );
13
+ };
14
+
15
+ export default AuthRoutes;
@@ -0,0 +1,15 @@
1
+ import { Router, Route } from 'preact-iso';
2
+
3
+ import Home from '../pages/Home';
4
+ import RedirectRoute from '../components/RedirectRoute';
5
+
6
+ const MainRoutes = () => {
7
+ return (
8
+ <Router>
9
+ <Route path="/" component={Home} />
10
+ <Route default component={() => <RedirectRoute to="/" />} />
11
+ </Router>
12
+ );
13
+ };
14
+
15
+ export default MainRoutes;
@@ -0,0 +1,15 @@
1
+ import { Router, Route } from 'preact-iso';
2
+
3
+ import Onboarding from '../pages/Onboarding';
4
+ import RedirectRoute from '../components/RedirectRoute';
5
+
6
+ const OnboardingRoutes = () => {
7
+ return (
8
+ <Router>
9
+ <Route path="/onboarding" component={Onboarding} />
10
+ <Route default component={() => <RedirectRoute to="/onboarding" />} />
11
+ </Router>
12
+ );
13
+ };
14
+
15
+ export default OnboardingRoutes;
@@ -0,0 +1,37 @@
1
+ import { LocationProvider } from 'preact-iso';
2
+ import MainRoutes from './MainRoutes';
3
+ import AuthRoutes from './AuthRoutes';
4
+ import OnboardingRoutes from './OnboardingRoutes';
5
+ import SplashScreen from '../components/SplashScreen';
6
+ import { useAuth } from '../hooks/useAuth';
7
+ import { auth } from '../stores/auth.store';
8
+
9
+ const NavigationContent = () => {
10
+ useAuth();
11
+
12
+ const { initialized, user, onboardingCompleted } = auth.value;
13
+
14
+ if (!initialized) {
15
+ return <SplashScreen />;
16
+ }
17
+
18
+ if (!user) {
19
+ return <AuthRoutes />;
20
+ }
21
+
22
+ if (!onboardingCompleted) {
23
+ return <OnboardingRoutes />;
24
+ }
25
+
26
+ return <MainRoutes />;
27
+ };
28
+
29
+ const Navigations = () => {
30
+ return (
31
+ <LocationProvider>
32
+ <NavigationContent />
33
+ </LocationProvider>
34
+ );
35
+ };
36
+
37
+ export default Navigations;