chore: restructure packages of the project (#7)

* chore: restructure validation package

* chore: move zod only to validation package

* chore: rename packages from alparr to homarr

* chore: move mantine core, dates and icons library to ui package, move most other mantine packages to seperate packages for further customization and centralization

* chore: fix formatting

* fix: wrong typecheck command in turbo generator

* chore: fix formatting

* chore: address pull request feedback

* chore: fix ci check issues
This commit is contained in:
Meier Lukas
2024-01-02 14:18:37 +01:00
committed by GitHub
parent a082f70470
commit fa19966fcc
67 changed files with 562 additions and 304 deletions

View File

@@ -1,23 +1,33 @@
// Importing env files here to validate on build
import "./src/env.mjs";
import "@alparr/auth/env.mjs";
import "@homarr/auth/env.mjs";
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
/** Enables hot reloading for local packages without a build step */
transpilePackages: [
"@alparr/api",
"@alparr/auth",
"@alparr/db",
"@alparr/ui",
"@alparr/validation",
"@homarr/api",
"@homarr/auth",
"@homarr/db",
"@homarr/ui",
"@homarr/validation",
"@homarr/form",
"@homarr/notifications",
"@homarr/spotlight",
],
/** We already do linting and typechecking as separate tasks in CI */
eslint: { ignoreDuringBuilds: true },
typescript: { ignoreBuildErrors: true },
experimental: {
optimizePackageImports: ["@mantine/core", "@mantine/hooks"],
optimizePackageImports: [
"@mantine/core",
"@mantine/hooks",
"@mantine/dates",
"@mantine/notifications",
"@mantine/form",
"@mantine/spotlight",
],
},
};

View File

@@ -1,5 +1,5 @@
{
"name": "@alparr/nextjs",
"name": "@homarr/nextjs",
"version": "0.1.0",
"private": true,
"scripts": {
@@ -13,21 +13,18 @@
"with-env": "dotenv -e ../../.env --"
},
"dependencies": {
"@alparr/api": "workspace:^0.1.0",
"@alparr/auth": "workspace:^0.1.0",
"@alparr/db": "workspace:^0.1.0",
"@alparr/translation": "workspace:^",
"@alparr/ui": "workspace:^0.1.0",
"@alparr/validation": "workspace:^0.1.0",
"@mantine/core": "^7.3.1",
"@mantine/dates": "^7.3.1",
"@mantine/form": "^7.3.1",
"@homarr/api": "workspace:^0.1.0",
"@homarr/auth": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/notifications": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/spotlight": "workspace:^0.1.0",
"@homarr/form": "workspace:^0.1.0",
"@mantine/hooks": "^7.3.1",
"@mantine/notifications": "^7.3.1",
"@mantine/spotlight": "^7.3.1",
"@mantine/tiptap": "^7.3.1",
"@t3-oss/env-nextjs": "^0.7.1",
"@tabler/icons-react": "^2.42.0",
"@tanstack/react-query": "^5.8.7",
"@tanstack/react-query-devtools": "^5.8.7",
"@tanstack/react-query-next-experimental": "5.8.7",
@@ -43,13 +40,12 @@
"postcss-preset-mantine": "^1.11.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"superjson": "2.2.1",
"zod": "^3.22.2"
"superjson": "2.2.1"
},
"devDependencies": {
"@alparr/eslint-config": "workspace:^0.2.0",
"@alparr/prettier-config": "workspace:^0.1.0",
"@alparr/tsconfig": "workspace:^0.1.0",
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^18.18.13",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
@@ -61,10 +57,10 @@
"eslintConfig": {
"root": true,
"extends": [
"@alparr/eslint-config/base",
"@alparr/eslint-config/nextjs",
"@alparr/eslint-config/react"
"@homarr/eslint-config/base",
"@homarr/eslint-config/nextjs",
"@homarr/eslint-config/react"
]
},
"prettier": "@alparr/prettier-config"
"prettier": "@homarr/prettier-config"
}

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,7 +1,7 @@
import type { PropsWithChildren } from "react";
import { defaultLocale } from "@alparr/translation";
import { I18nProviderClient } from "@alparr/translation/client";
import { defaultLocale } from "@homarr/translation";
import { I18nProviderClient } from "@homarr/translation/client";
export const NextInternationalProvider = ({
children,

View File

@@ -2,21 +2,21 @@
import { useState } from "react";
import { useRouter } from "next/navigation";
import { signIn } from "@homarr/auth/client";
import { useForm, zodResolver } from "@homarr/form";
import { useScopedI18n } from "@homarr/translation/client";
import {
Alert,
Button,
IconAlertTriangle,
PasswordInput,
rem,
Stack,
TextInput,
} from "@mantine/core";
import { useForm, zodResolver } from "@mantine/form";
import { IconAlertTriangle } from "@tabler/icons-react";
import type { z } from "zod";
import { signIn } from "@alparr/auth/client";
import { useScopedI18n } from "@alparr/translation/client";
import { signInSchema } from "@alparr/validation";
} from "@homarr/ui";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
export const LoginForm = () => {
const t = useScopedI18n("user");
@@ -24,7 +24,7 @@ export const LoginForm = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string>();
const form = useForm<FormType>({
validate: zodResolver(signInSchema),
validate: zodResolver(validation.user.signIn),
initialValues: {
name: "",
password: "",
@@ -79,4 +79,4 @@ export const LoginForm = () => {
);
};
type FormType = z.infer<typeof signInSchema>;
type FormType = z.infer<typeof validation.user.signIn>;

View File

@@ -1,6 +1,5 @@
import { Card, Center, Stack, Text, Title } from "@mantine/core";
import { getScopedI18n } from "@alparr/translation/server";
import { getScopedI18n } from "@homarr/translation/server";
import { Card, Center, Stack, Text, Title } from "@homarr/ui";
import { LogoWithTitle } from "~/components/layout/logo";
import { LoginForm } from "./_components/login-form";

View File

@@ -1,14 +1,17 @@
"use client";
import { useRouter } from "next/navigation";
import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
import { useForm, zodResolver } from "@mantine/form";
import type { z } from "zod";
import { useScopedI18n } from "@alparr/translation/client";
import { initUserSchema } from "@alparr/validation";
import { useForm, zodResolver } from "@homarr/form";
import {
showErrorNotification,
showSuccessNotification,
} from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { Button, PasswordInput, Stack, TextInput } from "@homarr/ui";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { showErrorNotification, showSuccessNotification } from "~/notification";
import { api } from "~/utils/api";
export const InitUserForm = () => {
@@ -16,7 +19,7 @@ export const InitUserForm = () => {
const t = useScopedI18n("user");
const { mutateAsync, error, isPending } = api.user.initUser.useMutation();
const form = useForm<FormType>({
validate: zodResolver(initUserSchema),
validate: zodResolver(validation.user.init),
validateInputOnBlur: true,
validateInputOnChange: true,
initialValues: {
@@ -75,4 +78,4 @@ export const InitUserForm = () => {
);
};
type FormType = z.infer<typeof initUserSchema>;
type FormType = z.infer<typeof validation.user.init>;

View File

@@ -1,8 +1,8 @@
import { notFound } from "next/navigation";
import { Card, Center, Stack, Text, Title } from "@mantine/core";
import { db } from "@alparr/db";
import { getScopedI18n } from "@alparr/translation/server";
import { db } from "@homarr/db";
import { getScopedI18n } from "@homarr/translation/server";
import { Card, Center, Stack, Text, Title } from "@homarr/ui";
import { LogoWithTitle } from "~/components/layout/logo";
import { InitUserForm } from "./_components/init-user-form";

View File

@@ -1,15 +1,17 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "@mantine/core/styles.css";
import "@mantine/dates/styles.css";
import "@mantine/notifications/styles.css";
import "@homarr/ui/styles.css";
import "@homarr/notifications/styles.css";
import { headers } from "next/headers";
import { ColorSchemeScript, MantineProvider } from "@mantine/core";
import { Notifications } from "@mantine/notifications";
import { uiConfiguration } from "@alparr/ui";
import { Notifications } from "@homarr/notifications";
import {
ColorSchemeScript,
MantineProvider,
uiConfiguration,
} from "@homarr/ui";
import { NextInternationalProvider } from "./_client-providers/next-international";
import { TRPCReactProvider } from "./_client-providers/trpc";

View File

@@ -1,4 +1,4 @@
import { Center, Loader } from "@mantine/core";
import { Center, Loader } from "@homarr/ui";
export default function CommonLoading() {
return (

View File

@@ -1,4 +1,4 @@
import { Center } from "@mantine/core";
import { Center } from "@homarr/ui";
export default function CommonNotFound() {
return <Center h="100vh">404</Center>;

View File

@@ -1,7 +1,6 @@
import { Button, Stack, Title } from "@mantine/core";
import { auth } from "@alparr/auth";
import { db } from "@alparr/db";
import { auth } from "@homarr/auth";
import { db } from "@homarr/db";
import { Button, Stack, Title } from "@homarr/ui";
export default async function HomePage() {
const currentSession = await auth();

View File

@@ -1,6 +1,6 @@
import type { NextRequest } from "next/server";
import { createHandlers } from "@alparr/auth";
import { createHandlers } from "@homarr/auth";
export const GET = async (req: NextRequest) => {
return await createHandlers(isCredentialsRequest(req)).handlers.GET(req);

View File

@@ -1,7 +1,7 @@
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter, createTRPCContext } from "@alparr/api";
import { auth } from "@alparr/auth";
import { appRouter, createTRPCContext } from "@homarr/api";
import { auth } from "@homarr/auth";
/**
* Configure basic CORS headers

View File

@@ -1,12 +1,13 @@
import Image from "next/image";
import { Group, Title } from "@mantine/core";
import { Group, Title } from "@homarr/ui";
interface LogoProps {
size: number;
}
export const Logo = ({ size = 60 }: LogoProps) => (
<Image src="/logo/alparr.png" alt="Alparr logo" width={size} height={size} />
<Image src="/logo/homarr.png" alt="homarr logo" width={size} height={size} />
);
export const LogoWithTitle = () => (

View File

@@ -1,6 +1,6 @@
import type { NextRequest } from "next/server";
import { I18nMiddleware } from "@alparr/translation/middleware";
import { I18nMiddleware } from "@homarr/translation/middleware";
export function middleware(request: NextRequest) {
return I18nMiddleware(request);

View File

@@ -1,20 +0,0 @@
import { rem } from "@mantine/core";
import type { NotificationData } from "@mantine/notifications";
import { notifications } from "@mantine/notifications";
import { IconCheck, IconX } from "@tabler/icons-react";
type CommonNotificationProps = Pick<NotificationData, "title" | "message">;
export const showSuccessNotification = (props: CommonNotificationProps) =>
notifications.show({
...props,
color: "teal",
icon: <IconCheck size={rem(20)} />,
});
export const showErrorNotification = (props: CommonNotificationProps) =>
notifications.show({
...props,
color: "red",
icon: <IconX size={rem(20)} />,
});

View File

@@ -1,7 +1,7 @@
import { createTRPCReact } from "@trpc/react-query";
import type { AppRouter } from "@alparr/api";
import type { AppRouter } from "@homarr/api";
export const api = createTRPCReact<AppRouter>();
export { type RouterInputs, type RouterOutputs } from "@alparr/api";
export { type RouterInputs, type RouterOutputs } from "@homarr/api";

View File

@@ -1,5 +1,5 @@
{
"extends": "@alparr/tsconfig/base.json",
"extends": "@homarr/tsconfig/base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {