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"
|
||||
|
||||
# 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 { MonitorPage } from './pages/Monitor';
|
||||
import { WebsitePage } from './pages/Website';
|
||||
import { useGlobalConfig } from './hooks/useConfig';
|
||||
import { useInjectWebsiteScript } from './hooks/useInjectWebsiteScript';
|
||||
|
||||
export const AppRoutes: React.FC = React.memo(() => {
|
||||
const { info } = useUserStore();
|
||||
const { allowRegister } = useGlobalConfig();
|
||||
|
||||
useInjectWebsiteScript();
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
@ -30,7 +35,7 @@ export const AppRoutes: React.FC = React.memo(() => {
|
||||
) : (
|
||||
<Route>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/register" element={<Register />} />
|
||||
{allowRegister && <Route path="/register" element={<Register />} />}
|
||||
</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 { setJWT } from '../api/auth';
|
||||
import { setUserInfo } from '../store/user';
|
||||
import { useGlobalConfig } from '../hooks/useConfig';
|
||||
|
||||
export const Login: React.FC = React.memo(() => {
|
||||
const navigate = useNavigate();
|
||||
@ -20,6 +21,7 @@ export const Login: React.FC = React.memo(() => {
|
||||
setUserInfo(res.info);
|
||||
navigate('/dashboard');
|
||||
});
|
||||
const { allowRegister } = useGlobalConfig();
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex justify-center items-center">
|
||||
@ -51,6 +53,8 @@ export const Login: React.FC = React.memo(() => {
|
||||
Login
|
||||
</Button>
|
||||
</Form.Item>
|
||||
|
||||
{allowRegister && (
|
||||
<Form.Item>
|
||||
<Button
|
||||
size="large"
|
||||
@ -63,6 +67,7 @@ export const Login: React.FC = React.memo(() => {
|
||||
Register
|
||||
</Button>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</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 { userRouter } from './user';
|
||||
import { workspaceRouter } from './workspace';
|
||||
import { globalRouter } from './global';
|
||||
|
||||
export const appRouter = router({
|
||||
global: globalRouter,
|
||||
user: userRouter,
|
||||
workspace: workspaceRouter,
|
||||
website: websiteRouter,
|
||||
|
Loading…
Reference in New Issue
Block a user