feat: add about page (#388)
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
.root {
|
||||||
|
border-radius: var(--mantine-radius-sm);
|
||||||
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-gray-0),
|
||||||
|
var(--mantine-color-dark-6)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-gray-0),
|
||||||
|
var(--mantine-color-dark-6)
|
||||||
|
);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
transition: transform 150ms ease;
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
transform: scale(1.015);
|
||||||
|
z-index: 1;
|
||||||
|
background-color: var(--mantine-color-body);
|
||||||
|
border-color: light-dark(
|
||||||
|
var(--mantine-color-gray-2),
|
||||||
|
var(--mantine-color-dark-4)
|
||||||
|
);
|
||||||
|
box-shadow: var(--mantine-shadow-md);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron {
|
||||||
|
&[data-rotate] {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
93
apps/nextjs/src/app/[locale]/manage/about/page.tsx
Normal file
93
apps/nextjs/src/app/[locale]/manage/about/page.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionControl,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Center,
|
||||||
|
Group,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { IconLanguage, IconLibrary, IconUsers } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
import { getScopedI18n } from "@homarr/translation/server";
|
||||||
|
|
||||||
|
import { getPackageAttributes } from "~/versions/package-reader";
|
||||||
|
import logo from "../../../../../public/logo/logo.png";
|
||||||
|
import classes from "./accordion.module.css";
|
||||||
|
|
||||||
|
export async function generateMetadata() {
|
||||||
|
const t = await getScopedI18n("management");
|
||||||
|
const metaTitle = `${t("metaTitle")} • Homarr`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: metaTitle,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function AboutPage() {
|
||||||
|
const t = await getScopedI18n("management.page.about");
|
||||||
|
const attributes = getPackageAttributes();
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Center w="100%">
|
||||||
|
<Group py="lg">
|
||||||
|
<Image src={logo} width={100} height={100} alt="" />
|
||||||
|
<Stack gap={0}>
|
||||||
|
<Title order={1} tt="uppercase">
|
||||||
|
Homarr
|
||||||
|
</Title>
|
||||||
|
<Title order={2}>
|
||||||
|
{t("version", { version: attributes.version })}
|
||||||
|
</Title>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
</Center>
|
||||||
|
<Text mb="xl">{t("text")}</Text>
|
||||||
|
|
||||||
|
<Accordion classNames={classes}>
|
||||||
|
<AccordionItem value="contributors">
|
||||||
|
<AccordionControl icon={<IconUsers size="1rem" />}>
|
||||||
|
{t("accordion.contributors.title")}
|
||||||
|
</AccordionControl>
|
||||||
|
<AccordionPanel></AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="translators">
|
||||||
|
<AccordionControl icon={<IconLanguage size="1rem" />}>
|
||||||
|
{t("accordion.translators.title")}
|
||||||
|
</AccordionControl>
|
||||||
|
<AccordionPanel></AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="libraries">
|
||||||
|
<AccordionControl icon={<IconLibrary size="1rem" />}>
|
||||||
|
<Stack gap={0}>
|
||||||
|
<Text>{t("accordion.libraries.title")}</Text>
|
||||||
|
<Text size="sm" c="dimmed">
|
||||||
|
{t("accordion.libraries.subtitle", {
|
||||||
|
count: Object.keys(attributes.dependencies).length,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</AccordionControl>
|
||||||
|
<AccordionPanel>
|
||||||
|
<List>
|
||||||
|
{Object.entries(attributes.dependencies).map(([key, value]) => (
|
||||||
|
<ListItem key={key}>
|
||||||
|
{value.includes("workspace:") ? (
|
||||||
|
<Text>{key}</Text>
|
||||||
|
) : (
|
||||||
|
<a href={`https://www.npmjs.com/package/${key}`}>{key}</a>
|
||||||
|
)}
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
4
apps/nextjs/src/react-app-env.d.ts
vendored
Normal file
4
apps/nextjs/src/react-app-env.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
declare module "*.png";
|
||||||
|
declare module "*.svg";
|
||||||
|
declare module "*.jpeg";
|
||||||
|
declare module "*.jpg";
|
||||||
13
apps/nextjs/src/versions/package-reader.ts
Normal file
13
apps/nextjs/src/versions/package-reader.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import packageJson from "~/../package.json";
|
||||||
|
|
||||||
|
const getPackageVersion = () => packageJson.version;
|
||||||
|
const getDependencies = (): PackageJsonDependencies => packageJson.dependencies;
|
||||||
|
|
||||||
|
export const getPackageAttributes = () => {
|
||||||
|
return {
|
||||||
|
version: getPackageVersion(),
|
||||||
|
dependencies: getDependencies(),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type PackageJsonDependencies = { [key in string]: string };
|
||||||
@@ -948,6 +948,22 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
about: {
|
||||||
|
version: "Version {version}",
|
||||||
|
text: "Homarr is a community driven open source project that is being maintained by volunteers. Thanks to these people, Homarr has been a growing project since 2021. Our team is working completely remote from many different countries on Homarr in their leisure time for no compensation.",
|
||||||
|
accordion: {
|
||||||
|
contributors: {
|
||||||
|
title: "Contributors",
|
||||||
|
},
|
||||||
|
translators: {
|
||||||
|
title: "Translators",
|
||||||
|
},
|
||||||
|
libraries: {
|
||||||
|
title: "Libraries",
|
||||||
|
subtitle: "{count} used",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
Reference in New Issue
Block a user