Added basic frontend setup
This commit is contained in:
4
apps/frontend/.dockerignore
Normal file
4
apps/frontend/.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.react-router
|
||||||
|
build
|
||||||
|
node_modules
|
||||||
|
README.md
|
||||||
7
apps/frontend/.gitignore
vendored
Normal file
7
apps/frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
|
# React Router
|
||||||
|
/.react-router/
|
||||||
|
/build/
|
||||||
15
apps/frontend/app/app.css
Normal file
15
apps/frontend/app/app.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
|
||||||
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
@apply bg-white dark:bg-gray-950;
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
apps/frontend/app/root.tsx
Normal file
59
apps/frontend/app/root.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router';
|
||||||
|
|
||||||
|
import type { Route } from './+types/root';
|
||||||
|
import './app.css';
|
||||||
|
import { Theme } from '@radix-ui/themes';
|
||||||
|
|
||||||
|
export const links: Route.LinksFunction = () => [];
|
||||||
|
|
||||||
|
export function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<Meta />
|
||||||
|
<Links />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{children}
|
||||||
|
<ScrollRestoration />
|
||||||
|
<Scripts />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<Theme>
|
||||||
|
<Outlet />
|
||||||
|
</Theme>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
|
||||||
|
let message = 'Oops!';
|
||||||
|
let details = 'An unexpected error occurred.';
|
||||||
|
let stack: string | undefined;
|
||||||
|
|
||||||
|
if (isRouteErrorResponse(error)) {
|
||||||
|
message = error.status === 404 ? '404' : 'Error';
|
||||||
|
details = error.status === 404 ? 'The requested page could not be found.' : error.statusText || details;
|
||||||
|
} else if (import.meta.env.DEV && error && error instanceof Error) {
|
||||||
|
details = error.message;
|
||||||
|
stack = error.stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="pt-16 p-4 container mx-auto">
|
||||||
|
<h1>{message}</h1>
|
||||||
|
<p>{details}</p>
|
||||||
|
{stack && (
|
||||||
|
<pre className="w-full p-4 overflow-x-auto">
|
||||||
|
<code>{stack}</code>
|
||||||
|
</pre>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
3
apps/frontend/app/routes.ts
Normal file
3
apps/frontend/app/routes.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { type RouteConfig, index } from "@react-router/dev/routes";
|
||||||
|
|
||||||
|
export default [index("routes/home.tsx")] satisfies RouteConfig;
|
||||||
10
apps/frontend/app/routes/home.tsx
Normal file
10
apps/frontend/app/routes/home.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Text } from '@radix-ui/themes';
|
||||||
|
import type { Route } from './+types/home';
|
||||||
|
|
||||||
|
export function meta({}: Route.MetaArgs) {
|
||||||
|
return [{ title: 'YANPM' }, { name: 'description', content: 'Welcome to Yet Another Nginx Proxy Manager!' }];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return <Text>Welcome to Yet Another Nginx Proxy Manager!</Text>;
|
||||||
|
}
|
||||||
33
apps/frontend/package.json
Normal file
33
apps/frontend/package.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "react-router build",
|
||||||
|
"dev": "react-router dev",
|
||||||
|
"start": "react-router-serve ./build/server/index.js",
|
||||||
|
"typecheck": "react-router typegen && tsc"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/themes": "^3.2.1",
|
||||||
|
"@react-router/node": "^7.9.2",
|
||||||
|
"@react-router/serve": "^7.9.2",
|
||||||
|
"isbot": "^5.1.31",
|
||||||
|
"radix-ui": "^1.4.3",
|
||||||
|
"react": "^19.1.1",
|
||||||
|
"react-dom": "^19.1.1",
|
||||||
|
"react-router": "^7.9.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@react-router/dev": "^7.9.2",
|
||||||
|
"@tailwindcss/vite": "^4.1.13",
|
||||||
|
"@types/node": "^22",
|
||||||
|
"@types/react": "^19.1.13",
|
||||||
|
"@types/react-dom": "^19.1.9",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
|
"tailwindcss": "^4.1.13",
|
||||||
|
"typescript": "^5.9.2",
|
||||||
|
"vite": "^7.1.7",
|
||||||
|
"vite-tsconfig-paths": "^5.1.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
4748
apps/frontend/pnpm-lock.yaml
generated
Normal file
4748
apps/frontend/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
apps/frontend/public/favicon.ico
Normal file
BIN
apps/frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
5
apps/frontend/react-router.config.ts
Normal file
5
apps/frontend/react-router.config.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import type { Config } from '@react-router/dev/config';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
ssr: false,
|
||||||
|
} satisfies Config;
|
||||||
22
apps/frontend/tsconfig.json
Normal file
22
apps/frontend/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"include": ["**/*", "**/.server/**/*", "**/.client/**/*", ".react-router/types/**/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
||||||
|
"types": ["node", "vite/client"],
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ES2022",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"rootDirs": [".", "./.react-router/types"],
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./app/*"]
|
||||||
|
},
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
}
|
||||||
9
apps/frontend/vite.config.ts
Normal file
9
apps/frontend/vite.config.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { reactRouter } from '@react-router/dev/vite';
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
|
||||||
|
appType: 'spa',
|
||||||
|
});
|
||||||
12
justfile
12
justfile
@@ -40,3 +40,15 @@ migrate *args:
|
|||||||
generate-entity:
|
generate-entity:
|
||||||
# delegate to cli
|
# delegate to cli
|
||||||
just cli db:migrate_and_generate --output-path ../../public/database/src/generated/entities
|
just cli db:migrate_and_generate --output-path ../../public/database/src/generated/entities
|
||||||
|
|
||||||
|
build-frontend:
|
||||||
|
# build frontend assets
|
||||||
|
cd apps/frontend && \
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
build-backend:
|
||||||
|
# build backend server
|
||||||
|
cd apps/api && \
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
build: build-frontend build-backend
|
||||||
|
|||||||
Reference in New Issue
Block a user