Merge branch 'dev' into about-page
This commit is contained in:
55
src/pages/401.tsx
Normal file
55
src/pages/401.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Button, Center, Stack, Title, Text, createStyles } from "@mantine/core";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import Image from "next/image";
|
||||
import Head from "next/head";
|
||||
import { MainLayout } from "~/components/layout/Templates/MainLayout";
|
||||
import Link from "next/link";
|
||||
|
||||
import imageAccessDenied from '~/images/undraw_secure_login_pdn4.svg';
|
||||
import { pageAccessDeniedNamespaces } from "~/tools/server/translation-namespaces";
|
||||
import { getServerSideTranslations } from "~/tools/server/getServerSideTranslations";
|
||||
import { GetServerSidePropsContext } from "next";
|
||||
|
||||
export default function Custom401() {
|
||||
const { classes } = useStyles();
|
||||
const { t } = useTranslation('layout/errors/access-denied');
|
||||
return (
|
||||
<MainLayout>
|
||||
<Center h="100dvh" w="100dvw">
|
||||
<Head>
|
||||
<title>Access denied • Homarr</title>
|
||||
</Head>
|
||||
<Stack maw={500} p="xl">
|
||||
<Image className={classes.image} src={imageAccessDenied} width={200} height={200} alt="" />
|
||||
<Title>{t('title')}</Title>
|
||||
<Text>{t('text')}</Text>
|
||||
|
||||
<Button component={Link} variant="light" href="/auth/login">
|
||||
{t('switchAccount')}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ req, res, locale }: GetServerSidePropsContext) {
|
||||
const translations = await getServerSideTranslations(
|
||||
[...pageAccessDeniedNamespaces, 'common'],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
);
|
||||
return {
|
||||
props: {
|
||||
...translations,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const useStyles = createStyles(() => ({
|
||||
image: {
|
||||
margin: '0 auto',
|
||||
display: 'block',
|
||||
},
|
||||
}));
|
||||
@@ -61,7 +61,7 @@ function App(
|
||||
const analyticsEnabled = pageProps.analyticsEnabled ?? true;
|
||||
// TODO: make mapping from our locales to moment locales
|
||||
const language = getLanguageByCode(pageProps.session?.user?.language ?? 'en');
|
||||
require(`dayjs/locale/${language.locale}.js`);
|
||||
if (language.locale !== 'cr') require(`dayjs/locale/${language.locale}.js`);
|
||||
dayjs.locale(language.locale);
|
||||
|
||||
const [primaryColor, setPrimaryColor] = useState<MantineTheme['primaryColor']>(
|
||||
@@ -101,12 +101,18 @@ function App(
|
||||
return (
|
||||
<>
|
||||
<CommonHead />
|
||||
{pageProps.session && pageProps.session.user.language === 'cr' && (
|
||||
<>
|
||||
<Script type="text/javascript" src="//cdn.crowdin.com/jipt/jipt.js" />
|
||||
<Script type="text/javascript">var _jipt = []; _jipt.push(['project', 'homarr']);</Script>
|
||||
</>
|
||||
)}
|
||||
{analyticsEnabled === true && (
|
||||
<Script
|
||||
src="https://umami.homarr.dev/script.js"
|
||||
data-website-id="f133f10c-30a7-4506-889c-3a803f328fa4"
|
||||
strategy="lazyOnload"
|
||||
/>
|
||||
src="https://umami.homarr.dev/script.js"
|
||||
data-website-id="f133f10c-30a7-4506-889c-3a803f328fa4"
|
||||
strategy="lazyOnload"
|
||||
/>
|
||||
)}
|
||||
<SessionProvider session={pageProps.session}>
|
||||
<ColorSchemeProvider {...pageProps}>
|
||||
|
||||
@@ -15,12 +15,11 @@ import { ConfigType } from '~/types/config';
|
||||
|
||||
export default function BoardPage({
|
||||
config: initialConfig,
|
||||
dockerEnabled,
|
||||
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
|
||||
useInitConfig(initialConfig);
|
||||
|
||||
return (
|
||||
<BoardLayout dockerEnabled={dockerEnabled}>
|
||||
<BoardLayout>
|
||||
<Dashboard />
|
||||
</BoardLayout>
|
||||
);
|
||||
@@ -28,7 +27,6 @@ export default function BoardPage({
|
||||
|
||||
type BoardGetServerSideProps = {
|
||||
config: ConfigType;
|
||||
dockerEnabled: boolean;
|
||||
_nextI18Next?: SSRConfig['_nextI18Next'];
|
||||
};
|
||||
|
||||
@@ -64,7 +62,7 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
const result = checkForSessionOrAskForLogin(
|
||||
ctx,
|
||||
session,
|
||||
() => config.settings.access.allowGuests || !!session?.user
|
||||
() => config.settings.access.allowGuests || session?.user != undefined
|
||||
);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -76,7 +74,6 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
primaryColor: config.settings.customization.colors.primary,
|
||||
secondaryColor: config.settings.customization.colors.secondary,
|
||||
primaryShade: config.settings.customization.colors.shade,
|
||||
dockerEnabled: !!env.DOCKER_HOST && !!env.DOCKER_PORT,
|
||||
...translations,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -44,6 +44,7 @@ import { MainLayout } from '~/components/layout/Templates/MainLayout';
|
||||
import { createTrpcServersideHelpers } from '~/server/api/helper';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { firstUpperCase } from '~/tools/shared/strings';
|
||||
import { api } from '~/utils/api';
|
||||
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
|
||||
@@ -275,22 +276,22 @@ const routeParamsSchema = z.object({
|
||||
slug: z.string(),
|
||||
});
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res, locale, params }) => {
|
||||
const routeParams = routeParamsSchema.safeParse(params);
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const routeParams = routeParamsSchema.safeParse(context.params);
|
||||
if (!routeParams.success) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const session = await getServerAuthSession({ req: context.req, res: context.res });
|
||||
|
||||
const result = checkForSessionOrAskForLogin(context, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const helpers = await createTrpcServersideHelpers({ req, res });
|
||||
const helpers = await createTrpcServersideHelpers({ req: context.req, res: context.res });
|
||||
|
||||
const config = await helpers.config.byName.fetch({ name: routeParams.data.slug });
|
||||
|
||||
@@ -305,9 +306,9 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res, locale,
|
||||
'settings/customization/gridstack',
|
||||
'settings/customization/access',
|
||||
],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
context.locale,
|
||||
context.req,
|
||||
context.res
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
|
||||
import { SSRConfig } from 'next-i18next';
|
||||
import { Dashboard } from '~/components/Dashboard/Dashboard';
|
||||
import { BoardLayout } from '~/components/layout/Templates/BoardLayout';
|
||||
import { useInitConfig } from '~/config/init';
|
||||
import { env } from '~/env';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { db } from '~/server/db';
|
||||
import { getDefaultBoardAsync } from '~/server/db/queries/userSettings';
|
||||
import { userSettings } from '~/server/db/schema';
|
||||
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { ConfigType } from '~/types/config';
|
||||
|
||||
export default function BoardPage({
|
||||
config: initialConfig,
|
||||
dockerEnabled,
|
||||
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
|
||||
useInitConfig(initialConfig);
|
||||
|
||||
return (
|
||||
<BoardLayout dockerEnabled={dockerEnabled}>
|
||||
<BoardLayout>
|
||||
<Dashboard />
|
||||
</BoardLayout>
|
||||
);
|
||||
@@ -45,15 +41,9 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
);
|
||||
const config = await getFrontendConfig(boardName);
|
||||
|
||||
if (!config?.settings?.access?.allowGuests && !session?.user) {
|
||||
return {
|
||||
notFound: true,
|
||||
props: {
|
||||
primaryColor: config.settings.customization.colors.primary,
|
||||
secondaryColor: config.settings.customization.colors.secondary,
|
||||
primaryShade: config.settings.customization.colors.shade,
|
||||
},
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -62,7 +52,6 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
primaryColor: config.settings.customization.colors.primary,
|
||||
secondaryColor: config.settings.customization.colors.secondary,
|
||||
primaryShade: config.settings.customization.colors.shade,
|
||||
dockerEnabled: !!env.DOCKER_HOST && !!env.DOCKER_PORT,
|
||||
...translations,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ import { getServerSideTranslations } from '~/tools/server/getServerSideTranslati
|
||||
import { OnlyKeysWithStructure } from '~/types/helpers';
|
||||
|
||||
import { type quickActions } from '../../../public/locales/en/manage/index.json';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
|
||||
const ManagementPage = () => {
|
||||
const { t } = useTranslation('manage/index');
|
||||
@@ -118,10 +119,9 @@ const QuickActionCard = ({ type, href }: QuickActionCardProps) => {
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { dockerRouter } from '~/server/api/routers/docker/router';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -54,24 +55,23 @@ export default function DockerPage({
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ locale, req, res }) => {
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const session = await getServerAuthSession({ req: context.req, res: context.res });
|
||||
const result = checkForSessionOrAskForLogin(context, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const caller = dockerRouter.createCaller({
|
||||
session: session,
|
||||
cookies: req.cookies,
|
||||
cookies: context.req.cookies,
|
||||
});
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
[...boardNamespaces, 'layout/manage', 'tools/docker'],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
context.locale,
|
||||
context.req,
|
||||
context.res
|
||||
);
|
||||
|
||||
let containers = [];
|
||||
|
||||
@@ -26,6 +26,7 @@ import { openDeleteUserModal } from '~/components/Manage/User/delete-user.modal'
|
||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { manageNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -180,11 +181,9 @@ const ManageUsersPage = () => {
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -20,6 +20,7 @@ import { openCreateInviteModal } from '~/components/Manage/User/Invite/create-in
|
||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { manageNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -152,11 +153,9 @@ const useStyles = createStyles(() => ({
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -71,7 +71,6 @@ const SettingsComponent = ({
|
||||
boardsData: RouterOutputs['boards']['all'];
|
||||
}) => {
|
||||
const languagesData = languages.map((language) => ({
|
||||
image: 'https://img.icons8.com/clouds/256/000000/futurama-bender.png',
|
||||
label: language.originalName,
|
||||
description: language.translatedName,
|
||||
value: language.shortName,
|
||||
@@ -199,8 +198,8 @@ const SelectItem = forwardRef<HTMLDivElement, ItemProps>(
|
||||
({ image, label, description, country, ...others }: ItemProps, ref) => (
|
||||
<div ref={ref} {...others}>
|
||||
<Group noWrap>
|
||||
<span className={`fi fi-${country?.toLowerCase()}`}></span>
|
||||
|
||||
{country !== 'CROWDIN' && <span className={`fi fi-${country?.toLowerCase()}`}></span>}
|
||||
{country === 'CROWDIN' && <img src={'https://support.crowdin.com/assets/logos/crowdin-dark-symbol.png'} alt={label} width={16} height={16} />}
|
||||
<div>
|
||||
<Text size="sm">{label}</Text>
|
||||
<Text size="xs" opacity={0.65}>
|
||||
|
||||
Reference in New Issue
Block a user