feat: add global config to control register feature and inject website id
This commit is contained in:
parent
461d819246
commit
a7f9870e64
@ -1 +1,8 @@
|
|||||||
|
# postgresql url
|
||||||
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
|
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
|
||||||
|
|
||||||
|
# Whether allow register user
|
||||||
|
ALLOW_REGISTER=
|
||||||
|
|
||||||
|
# For analyze tianji self
|
||||||
|
WEBSITE_ID=
|
||||||
|
@ -13,9 +13,14 @@ import React from 'react';
|
|||||||
import { trpc, trpcClient } from './api/trpc';
|
import { trpc, trpcClient } from './api/trpc';
|
||||||
import { MonitorPage } from './pages/Monitor';
|
import { MonitorPage } from './pages/Monitor';
|
||||||
import { WebsitePage } from './pages/Website';
|
import { WebsitePage } from './pages/Website';
|
||||||
|
import { useGlobalConfig } from './hooks/useConfig';
|
||||||
|
import { useInjectWebsiteScript } from './hooks/useInjectWebsiteScript';
|
||||||
|
|
||||||
export const AppRoutes: React.FC = React.memo(() => {
|
export const AppRoutes: React.FC = React.memo(() => {
|
||||||
const { info } = useUserStore();
|
const { info } = useUserStore();
|
||||||
|
const { allowRegister } = useGlobalConfig();
|
||||||
|
|
||||||
|
useInjectWebsiteScript();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
@ -30,7 +35,7 @@ export const AppRoutes: React.FC = React.memo(() => {
|
|||||||
) : (
|
) : (
|
||||||
<Route>
|
<Route>
|
||||||
<Route path="/login" element={<Login />} />
|
<Route path="/login" element={<Login />} />
|
||||||
<Route path="/register" element={<Register />} />
|
{allowRegister && <Route path="/register" element={<Register />} />}
|
||||||
</Route>
|
</Route>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
19
src/client/hooks/useConfig.ts
Normal file
19
src/client/hooks/useConfig.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { AppRouterOutput, trpc } from '../api/trpc';
|
||||||
|
|
||||||
|
const defaultGlobalConfig: AppRouterOutput['global']['config'] = {
|
||||||
|
allowRegister: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch settings from server
|
||||||
|
*/
|
||||||
|
export function useGlobalConfig(): AppRouterOutput['global']['config'] {
|
||||||
|
const { data = defaultGlobalConfig } = trpc.global.config.useQuery(
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
staleTime: 1000 * 60 * 60 * 1, // 1 hour
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
27
src/client/hooks/useDataReady.tsx
Normal file
27
src/client/hooks/useDataReady.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { DependencyList, useLayoutEffect, useRef } from 'react';
|
||||||
|
import { useEvent } from './useEvent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call once on data ready(validator return true)
|
||||||
|
*/
|
||||||
|
export function useDataReady(
|
||||||
|
validator: () => boolean,
|
||||||
|
cb: () => void,
|
||||||
|
deps?: DependencyList
|
||||||
|
) {
|
||||||
|
const isReadyRef = useRef(false);
|
||||||
|
|
||||||
|
const _validator = useEvent(validator);
|
||||||
|
const _callback = useEvent(cb);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (isReadyRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_validator() === true) {
|
||||||
|
_callback();
|
||||||
|
isReadyRef.current = true;
|
||||||
|
}
|
||||||
|
}, deps);
|
||||||
|
}
|
16
src/client/hooks/useInjectWebsiteScript.ts
Normal file
16
src/client/hooks/useInjectWebsiteScript.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { useGlobalConfig } from './useConfig';
|
||||||
|
import { useDataReady } from './useDataReady';
|
||||||
|
|
||||||
|
export function useInjectWebsiteScript() {
|
||||||
|
const { websiteId } = useGlobalConfig();
|
||||||
|
|
||||||
|
useDataReady(
|
||||||
|
() => typeof websiteId === 'string' && websiteId.length > 0,
|
||||||
|
() => {
|
||||||
|
const el = document.createElement('script');
|
||||||
|
el.src = location.origin + '/tracker.js';
|
||||||
|
el.setAttribute('data-website-id', String(websiteId));
|
||||||
|
document.head.append(el);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
@ -5,6 +5,7 @@ import { useRequest } from '../hooks/useRequest';
|
|||||||
import { trpc } from '../api/trpc';
|
import { trpc } from '../api/trpc';
|
||||||
import { setJWT } from '../api/auth';
|
import { setJWT } from '../api/auth';
|
||||||
import { setUserInfo } from '../store/user';
|
import { setUserInfo } from '../store/user';
|
||||||
|
import { useGlobalConfig } from '../hooks/useConfig';
|
||||||
|
|
||||||
export const Login: React.FC = React.memo(() => {
|
export const Login: React.FC = React.memo(() => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -20,6 +21,7 @@ export const Login: React.FC = React.memo(() => {
|
|||||||
setUserInfo(res.info);
|
setUserInfo(res.info);
|
||||||
navigate('/dashboard');
|
navigate('/dashboard');
|
||||||
});
|
});
|
||||||
|
const { allowRegister } = useGlobalConfig();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex justify-center items-center">
|
<div className="w-full h-full flex justify-center items-center">
|
||||||
@ -51,18 +53,21 @@ export const Login: React.FC = React.memo(() => {
|
|||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item>
|
|
||||||
<Button
|
{allowRegister && (
|
||||||
size="large"
|
<Form.Item>
|
||||||
htmlType="button"
|
<Button
|
||||||
block={true}
|
size="large"
|
||||||
onClick={() => {
|
htmlType="button"
|
||||||
navigate('/register');
|
block={true}
|
||||||
}}
|
onClick={() => {
|
||||||
>
|
navigate('/register');
|
||||||
Register
|
}}
|
||||||
</Button>
|
>
|
||||||
</Form.Item>
|
Register
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
14
src/server/trpc/routers/global.ts
Normal file
14
src/server/trpc/routers/global.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { publicProcedure, router } from '../trpc';
|
||||||
|
|
||||||
|
export const globalRouter = router({
|
||||||
|
config: publicProcedure.query(async ({ input }) => {
|
||||||
|
return {
|
||||||
|
allowRegister: checkEnvTrusty(process.env.ALLOW_REGISTER),
|
||||||
|
websiteId: process.env.WEBSITE_ID,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkEnvTrusty(env: string | undefined): boolean {
|
||||||
|
return env === '1' || env === 'true';
|
||||||
|
}
|
@ -4,8 +4,10 @@ import { websiteRouter } from './website';
|
|||||||
import { monitorRouter } from './monitor';
|
import { monitorRouter } from './monitor';
|
||||||
import { userRouter } from './user';
|
import { userRouter } from './user';
|
||||||
import { workspaceRouter } from './workspace';
|
import { workspaceRouter } from './workspace';
|
||||||
|
import { globalRouter } from './global';
|
||||||
|
|
||||||
export const appRouter = router({
|
export const appRouter = router({
|
||||||
|
global: globalRouter,
|
||||||
user: userRouter,
|
user: userRouter,
|
||||||
workspace: workspaceRouter,
|
workspace: workspaceRouter,
|
||||||
website: websiteRouter,
|
website: websiteRouter,
|
||||||
|
Loading…
Reference in New Issue
Block a user