easy-starter 1.2.1 → 2.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.
package/template/types.ts CHANGED
@@ -1,16 +1,51 @@
1
- import { APIDefinition, Endpoint, Token } from "typed-client-server-api";
1
+ import { APIDefinition, Endpoint } from "typed-client-server-api";
2
+
3
+ // --- AUTH START ---
4
+ import { UserDB } from "easy-user-auth/types";
5
+
6
+ export type UserProfile = {
7
+ name: string;
8
+ role: "admin" | "user";
9
+ };
10
+ // --- AUTH END ---
11
+
12
+ // --- OGIMAGE START ---
13
+ export type OgImageRecord = {
14
+ dateCreated: string;
15
+ file: {
16
+ type: "EASY_DB_FILE";
17
+ url: string;
18
+ };
19
+ };
20
+ // --- OGIMAGE END ---
2
21
 
3
22
  // The API type defines the contract between your React frontend and Express backend.
4
23
  // Every property here represents an endpoint. Both the client and server use this
5
- // to ensure type safety. If you change a parameter here, TypeScript will immediately
6
- // warn you if you forgot to update the frontend or backend!
24
+ // to ensure type safety.
7
25
  export type API = APIDefinition<{
8
26
  getItems: Endpoint<{}, Item[]>;
9
27
  getItem: Endpoint<{ id: string }, Item>;
10
28
  addItem: Endpoint<Omit<Item, "_id">, string>;
11
29
  removeItem: Endpoint<{ id: string }, boolean>;
12
30
 
31
+ /* --- ADMIN_NO_AUTH START --- */
13
32
  getEasyAnalyticsData: Endpoint<{ password: string, month: string }, any[]>;
33
+ /* --- ADMIN_NO_AUTH END --- */
34
+ // --- ADMIN_WITH_AUTH START ---
35
+ getEasyAnalyticsData: Endpoint<{ month: string }, any[]>;
36
+ // --- ADMIN_WITH_AUTH END ---
37
+
38
+ /* --- ADMIN_ERRORS_NO_AUTH START --- */
39
+ getEasyAnalyticsErrors: Endpoint<{ password: string, month: string }, any[]>;
40
+ /* --- ADMIN_ERRORS_NO_AUTH END --- */
41
+ // --- ADMIN_ERRORS_WITH_AUTH START ---
42
+ getEasyAnalyticsErrors: Endpoint<{ month: string }, any[]>;
43
+ // --- ADMIN_ERRORS_WITH_AUTH END ---
44
+
45
+ // --- ADMIN_USERS START ---
46
+ getUsers: Endpoint<{}, { _id: string, email: string, name: string, role: "admin" | "user" }[]>;
47
+ updateUserRole: Endpoint<{ userId: string, role: "admin" | "user" }, boolean>;
48
+ // --- ADMIN_USERS END ---
14
49
  }>;
15
50
 
16
51
  export type Item = {
@@ -23,4 +58,10 @@ export type Item = {
23
58
  // Each property represents a 'table' (or a separate JSON file).
24
59
  export type Database = {
25
60
  item: Item;
61
+ // --- AUTH START ---
62
+ user: UserDB<UserProfile>;
63
+ // --- AUTH END ---
64
+ // --- OGIMAGE START ---
65
+ "og-image": OgImageRecord;
66
+ // --- OGIMAGE END ---
26
67
  };
@@ -0,0 +1,29 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ define: {
7
+ "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
8
+ "global": "globalThis",
9
+ },
10
+ server: {
11
+ port: 5173,
12
+ proxy: {
13
+ "/api": {
14
+ target: "http://localhost:1111",
15
+ changeOrigin: true,
16
+ },
17
+ "/files": {
18
+ target: "http://localhost:1111",
19
+ changeOrigin: true,
20
+ },
21
+ // --- RESIZER START ---
22
+ "/images": {
23
+ target: "http://localhost:1111",
24
+ changeOrigin: true,
25
+ },
26
+ // --- RESIZER END ---
27
+ },
28
+ },
29
+ });
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "@parcel/config-default",
3
- "optimizers": {
4
- "*.html": []
5
- }
6
- }
Binary file
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <link rel="apple-touch-icon" sizes="180x180" href="./images/icon.png?width=180&height=180" />
7
- <link rel="icon" type="image/png" sizes="32x32" href="./images/icon.png?width=32&height=32" />
8
- <link rel="icon" type="image/png" sizes="16x16" href="./images/icon.png?width=16&height=16" />
9
- <link rel="manifest" href="./site.webmanifest" />
10
- <link rel="stylesheet" href="./styles.scss" />
11
- </head>
12
- <body>
13
- <div id="root"></div>
14
- <script type="module" src="index.tsx"></script>
15
- </body>
16
- </html>
@@ -1,292 +0,0 @@
1
- // Premium Dark Theme
2
- $bg: #09090b;
3
- $surface: #18181b;
4
- $primary: #6366f1; // Indigo
5
- $primary-hover: #818cf8;
6
- $text: #f4f4f5;
7
- $text-muted: #a1a1aa;
8
- $border: #27272a;
9
-
10
- body {
11
- font-family: 'Inter', system-ui, sans-serif;
12
- background-color: $bg;
13
- color: $text;
14
- margin: 0;
15
- padding: 0;
16
- line-height: 1.6;
17
- }
18
-
19
- a {
20
- color: $primary;
21
- text-decoration: none;
22
- font-weight: bold;
23
- transition: color 0.2s;
24
-
25
- &:hover {
26
- color: $primary-hover;
27
- }
28
- }
29
-
30
- main {
31
- max-width: 800px;
32
- margin: 50px auto;
33
- padding: 40px;
34
- background: $surface;
35
- border-radius: 16px;
36
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
37
- border: 1px solid $border;
38
- }
39
-
40
- header {
41
- text-align: center;
42
- margin-bottom: 40px;
43
-
44
- h1 {
45
- color: $primary;
46
- }
47
-
48
- p {
49
- color: $text-muted;
50
- }
51
-
52
- figure {
53
- width: 140px;
54
- height: 140px;
55
- margin: 0 auto 20px;
56
- background-image: url("./images/icon.png?as=webp");
57
- background-size: contain;
58
- background-repeat: no-repeat;
59
- background-position: center;
60
- }
61
- }
62
-
63
- section {
64
- margin-top: 40px;
65
- padding: 30px;
66
- background: rgba(255, 255, 255, 0.02);
67
- border-radius: 12px;
68
- border: 1px solid $border;
69
-
70
- ul {
71
- list-style: none;
72
- padding: 0;
73
-
74
- li {
75
- display: flex;
76
- align-items: center;
77
- justify-content: space-between;
78
- padding: 15px 20px;
79
- background: $bg;
80
- border-radius: 8px;
81
- margin-bottom: 12px;
82
- border: 1px solid $border;
83
- transition: transform 0.2s, border-color 0.2s;
84
-
85
- &:hover {
86
- transform: translateY(-2px);
87
- border-color: $primary;
88
- }
89
-
90
- nav {
91
- display: flex;
92
- gap: 8px;
93
- }
94
- }
95
- }
96
-
97
- article {
98
- padding: 0px 20px 10px;
99
- background: $bg;
100
- border-radius: 8px;
101
- border: 1px solid $primary;
102
- box-shadow: 0 0 15px rgba(99, 102, 241, 0.15);
103
-
104
- h3 {
105
- color: $primary;
106
- }
107
-
108
- p {
109
- margin: 5px 0;
110
- color: $text;
111
- }
112
- }
113
-
114
- form {
115
- display: flex;
116
- gap: 12px;
117
- flex-wrap: wrap;
118
- }
119
- }
120
-
121
- // Global Controls
122
- input {
123
- padding: 12px 16px;
124
- background: $bg;
125
- border: 1px solid $border;
126
- border-radius: 8px;
127
- color: $text;
128
- outline: none;
129
- transition: border-color 0.2s;
130
- flex: 1;
131
- min-width: 150px;
132
-
133
- &:focus {
134
- border-color: $primary;
135
- }
136
- }
137
-
138
- button {
139
- padding: 12px 24px;
140
- background: $primary;
141
- color: #fff;
142
- border: none;
143
- border-radius: 8px;
144
- cursor: pointer;
145
- font-weight: bold;
146
- transition: background 0.2s, transform 0.1s;
147
-
148
- &:hover:not(:disabled) {
149
- background: $primary-hover;
150
- transform: scale(1.02);
151
- }
152
-
153
- &.btn-danger {
154
- background: #ef4444;
155
-
156
- &:hover:not(:disabled) {
157
- background: #dc2626;
158
- }
159
- }
160
- }
161
-
162
- // --- ADMIN START ---
163
- // --- ADMIN DASHBOARD ---
164
- .admin-login {
165
- padding: 40px;
166
- max-width: 400px;
167
- margin: 0 auto;
168
- text-align: center;
169
-
170
- h2 {
171
- color: $text;
172
- }
173
-
174
- .back-link {
175
- margin-bottom: 20px;
176
- }
177
-
178
- form {
179
- display: flex;
180
- flex-direction: column;
181
- gap: 15px;
182
- margin-top: 20px;
183
- }
184
-
185
- }
186
-
187
- .admin-container {
188
- padding: 40px;
189
- max-width: 1200px;
190
- margin: 0 auto;
191
-
192
- .header {
193
- display: flex;
194
- justify-content: space-between;
195
- align-items: center;
196
- margin-bottom: 30px;
197
-
198
- h2 {
199
- margin: 0;
200
- color: $text;
201
- }
202
-
203
- a {
204
- color: $primary;
205
- text-decoration: none;
206
- font-weight: bold;
207
- }
208
- }
209
-
210
- .controls {
211
- display: flex;
212
- gap: 15px;
213
- align-items: center;
214
- margin-bottom: 30px;
215
- flex-wrap: wrap;
216
-
217
- strong {
218
- font-size: 1.1rem;
219
- color: $text;
220
- }
221
-
222
- .btn-logout {
223
- margin-left: auto;
224
- background: #ef4444;
225
-
226
- &:hover {
227
- background: #dc2626;
228
- }
229
- }
230
- }
231
-
232
- .chart-container {
233
- margin-bottom: 40px;
234
- background: rgba(255, 255, 255, 0.02);
235
- padding: 25px;
236
- border-radius: 12px;
237
- border: 1px solid $border;
238
-
239
- h3 {
240
- margin: 0 0 20px;
241
- font-size: 1.1rem;
242
- color: $text;
243
- }
244
-
245
- .chart {
246
- display: flex;
247
- align-items: flex-end;
248
- height: 150px;
249
- gap: 4px;
250
-
251
- .bar-wrapper {
252
- flex: 1;
253
- display: flex;
254
- flex-direction: column;
255
- align-items: center;
256
- justify-content: flex-end;
257
- height: 100%;
258
-
259
- .count {
260
- font-size: 11px;
261
- color: $text;
262
- margin-bottom: 4px;
263
- font-weight: bold;
264
- }
265
-
266
- .date {
267
- font-size: 10px;
268
- margin-top: 8px;
269
- color: $text-muted;
270
- }
271
-
272
- .bar {
273
- width: 100%;
274
- max-width: 24px;
275
- border-radius: 4px 4px 0 0;
276
- transition: height 0.3s ease;
277
- }
278
-
279
- .bar.active {
280
- background: $primary;
281
- }
282
- }
283
- }
284
- }
285
-
286
- .grid {
287
- display: grid;
288
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
289
- gap: 20px;
290
- }
291
- }
292
- // --- ADMIN END ---