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/README.md +33 -80
- package/bin/index.js +251 -49
- package/package.json +20 -11
- package/template/.cursorrules +42 -10
- package/template/README.md +129 -25
- package/template/env +0 -1
- package/template/gitignore +2 -1
- package/template/index.html +15 -0
- package/template/package.json +14 -8
- package/template/{src → public}/site.webmanifest +6 -12
- package/template/scripts/deploy.ts +3 -2
- package/template/server/index.tsx +264 -56
- package/template/server/mail.tsx +120 -0
- package/template/src/App.tsx +33 -7
- package/template/src/Router.tsx +13 -4
- package/template/src/components/Img.tsx +127 -0
- package/template/src/index.tsx +28 -1
- package/template/src/pages/Index.tsx +36 -6
- package/template/src/pages/NotFound.tsx +1 -1
- package/template/src/pages/ResetPassword.tsx +124 -0
- package/template/src/pages/admin/Admin.tsx +332 -85
- package/template/src/pages/admin/AnalyticsTab.tsx +71 -0
- package/template/src/pages/admin/ErrorsTab.tsx +46 -0
- package/template/src/pages/admin/UsersTab.tsx +54 -0
- package/template/src/services/api.ts +5 -7
- package/template/src/services/common.ts +34 -1
- package/template/src/styles.css +667 -0
- package/template/tsconfig.json +7 -2
- package/template/types.ts +44 -3
- package/template/vite.config.ts +29 -0
- package/template/.parcelrc +0 -6
- package/template/src/images/icon.png +0 -0
- package/template/src/index.html +0 -16
- package/template/src/styles.scss +0 -292
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
import { sendError } from "easy-analytics/client";
|
|
3
3
|
import { setServerUrl, getUseAPIFrontend, getAPIFrontend, setHeaders } from "typed-client-server-api/hooks";
|
|
4
|
+
|
|
5
|
+
// --- SSR START ---
|
|
4
6
|
import { useSSRHook } from "ssr-hook/client";
|
|
5
7
|
import { setSSROrigin } from "ssr-hook";
|
|
8
|
+
// --- SSR END ---
|
|
6
9
|
|
|
7
10
|
import { API } from "../../types";
|
|
8
11
|
|
|
@@ -14,13 +17,6 @@ export type UseSSRAPIType = {
|
|
|
14
17
|
};
|
|
15
18
|
|
|
16
19
|
|
|
17
|
-
if (process.env.NODE_ENV === "development") {
|
|
18
|
-
// In development mode, the frontend (Parcel) and backend (Express) run on different ports.
|
|
19
|
-
// We explicitly tell ssr-hook where the API backend is located.
|
|
20
|
-
setSSROrigin("http://localhost:1111");
|
|
21
|
-
setServerUrl("http://localhost:1111");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
20
|
let authorization = "";
|
|
25
21
|
|
|
26
22
|
setHeaders(() => ({
|
|
@@ -34,6 +30,7 @@ export function setAuthorizationHeader(newAuthorization: string) {
|
|
|
34
30
|
|
|
35
31
|
export const api = getAPIFrontend<API>();
|
|
36
32
|
export const useApi = getUseAPIFrontend<API>();
|
|
33
|
+
// --- SSR START ---
|
|
37
34
|
export const useSSRApi = new Proxy({}, {
|
|
38
35
|
get(target, prop: string) {
|
|
39
36
|
return (params: any) => {
|
|
@@ -42,6 +39,7 @@ export const useSSRApi = new Proxy({}, {
|
|
|
42
39
|
};
|
|
43
40
|
}
|
|
44
41
|
}) as UseSSRAPIType;
|
|
42
|
+
// --- SSR END ---
|
|
45
43
|
|
|
46
44
|
export function handleError(error?: unknown, errorInfo?: any) {
|
|
47
45
|
if (!error) return;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
// --- SSR START ---
|
|
1
2
|
import { useHeaders } from "ssr-hook";
|
|
3
|
+
// --- SSR END ---
|
|
2
4
|
import { useTitle } from "easy-page-router/react";
|
|
3
5
|
|
|
6
|
+
// --- NO_SSR START ---
|
|
7
|
+
import { useEffect } from "react";
|
|
8
|
+
// --- NO_SSR END ---
|
|
9
|
+
|
|
4
10
|
type UseHeadProps = {
|
|
5
11
|
title: string;
|
|
6
12
|
description: string;
|
|
@@ -10,12 +16,39 @@ type UseHeadProps = {
|
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
export function useHead({ title, description, image, canonical, lang }: UseHeadProps) {
|
|
19
|
+
// --- OGIMAGE START ---
|
|
20
|
+
const defaultOgImage = typeof window !== "undefined"
|
|
21
|
+
? `${window.location.origin}/og-image.png?path=${encodeURIComponent(window.location.pathname)}`
|
|
22
|
+
: "/og-image.png";
|
|
23
|
+
const resolvedImage = image || defaultOgImage;
|
|
24
|
+
// --- OGIMAGE END ---
|
|
25
|
+
/* --- NO_OGIMAGE START --- */
|
|
26
|
+
const resolvedImage = image || "/images/icon.png";
|
|
27
|
+
/* --- NO_OGIMAGE END --- */
|
|
28
|
+
|
|
29
|
+
// --- SSR START ---
|
|
13
30
|
useHeaders({
|
|
14
31
|
title,
|
|
15
32
|
description,
|
|
16
|
-
image:
|
|
33
|
+
image: resolvedImage,
|
|
17
34
|
canonical: canonical || (typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""),
|
|
18
35
|
lang,
|
|
19
36
|
});
|
|
37
|
+
// --- SSR END ---
|
|
38
|
+
// --- NO_SSR START ---
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (typeof document !== "undefined") {
|
|
41
|
+
const metaDesc = document.querySelector('meta[name="description"]');
|
|
42
|
+
if (metaDesc) {
|
|
43
|
+
metaDesc.setAttribute("content", description);
|
|
44
|
+
} else {
|
|
45
|
+
const meta = document.createElement("meta");
|
|
46
|
+
meta.name = "description";
|
|
47
|
+
meta.content = description;
|
|
48
|
+
document.head.appendChild(meta);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}, [description]);
|
|
52
|
+
// --- NO_SSR END ---
|
|
20
53
|
useTitle(title);
|
|
21
54
|
}
|