1
0
Fork 0

developing database

This commit is contained in:
minicx 2023-12-21 17:51:47 +03:00
parent 09e1420d26
commit 7364813fd2
13 changed files with 316 additions and 259 deletions

4
.gitignore vendored
View File

@ -1,8 +1,10 @@
node_modules/
src/database/prisma/client
**/build
**/.cache
.env
*.log
*.sqlite
package-lock.json
.vscode
.vscode
*.db*

View File

@ -8,7 +8,8 @@
"build": "remix build",
"start": "remix-serve ./build/index.js",
"lint": "npx eslint --fix .",
"typecheck": "tsc"
"typecheck": "tsc",
"migrate:dev":"npx prisma generate --schema src/database/prisma/schema.prisma"
},
"repository": {
"type": "git",
@ -43,6 +44,7 @@
},
"dependencies": {
"@nextui-org/react": "^2.2.9",
"@prisma/client": "^5.7.1",
"@remix-run/node": "^2.4.0",
"@remix-run/react": "^2.4.0",
"@remix-run/serve": "^2.4.0",

View File

@ -1,8 +1,8 @@
/** @type {import('@remix-run/dev').AppConfig} */
export default {
ignoredRouteFiles: ["**/.*"],
appDirectory: "src/app",
ignoredRouteFiles: ['**/.*'],
appDirectory: 'src/app',
// assetsBuildDirectory: "public/build",
// publicPath: "/build/",
// serverBuildPath: "build/index.js",
};
};

View File

@ -1,98 +1,108 @@
import { Link } from "@remix-run/react";
import { Link } from '@remix-run/react';
import {
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
NavbarMenuToggle,
NavbarMenu,
NavbarMenuItem,
Button
} from "@nextui-org/react";
import { useState } from "react";
Button,
} from '@nextui-org/react';
import { useState } from 'react';
export default function NavbarCom() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const menuItems = [
"Profile",
"Dashboard",
"Activity",
"Analytics",
"System",
"Deployments",
"My Settings",
"Team Settings",
"Help & Feedback",
"Log Out",
'Profile',
'Dashboard',
'Activity',
'Analytics',
'System',
'Deployments',
'My Settings',
'Team Settings',
'Help & Feedback',
'Log Out',
];
return(
return (
<Navbar
className="h-navbar"
isBordered
isMenuOpen={isMenuOpen}
onMenuOpenChange={setIsMenuOpen}
>
<NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle aria-label={isMenuOpen ? "Close menu" : "Open menu"} />
</NavbarContent>
<NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand>
<img src="./favicon.ico" />
<p className="ml-1 font-bold text-md text-inherit">Powered by EVRAZ</p>
</NavbarBrand>
</NavbarContent>
<NavbarContent className="hidden sm:flex gap-4" justify="center">
<NavbarBrand>
<img src="./favicon.ico" />
<p className="ml-1 font-bold text-xl text-inherit">Powered by EVRAZ</p>
</NavbarBrand>
<NavbarItem className="mx-auto">
<Link color="foreground" to="#">
Features
</Link>
</NavbarItem>
<NavbarItem isActive>
<Link to="#" aria-current="page">
Customers
</Link>
</NavbarItem>
<NavbarItem>
<Link color="foreground" to="#">
Integrations
</Link>
</NavbarItem>
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem className="hidden lg:flex">
<Link to="#">Login</Link>
</NavbarItem>
<NavbarItem>
<Button as={Link} color="primary" to="#" variant="flat">
Sign Up
</Button>
</NavbarItem>
</NavbarContent>
<NavbarMenu>
{menuItems.map((item, index) => (
<NavbarMenuItem key={`${item}-${index}`}>
<Link
className="w-full"
color={
index === 2 ? "warning" : index === menuItems.length - 1 ? "danger" : "foreground"
}
to="#"
>
{item}
</Link>
</NavbarMenuItem>
))}
</NavbarMenu>
</Navbar>
)
}
className="h-navbar"
isBordered
isMenuOpen={isMenuOpen}
onMenuOpenChange={setIsMenuOpen}
>
<NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle
aria-label={isMenuOpen ? 'Close menu' : 'Open menu'}
/>
</NavbarContent>
<NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand>
<img src="./favicon.ico" />
<p className="ml-1 font-bold text-md text-inherit">
Powered by EVRAZ
</p>
</NavbarBrand>
</NavbarContent>
<NavbarContent className="hidden sm:flex gap-4" justify="center">
<NavbarBrand>
<img src="./favicon.ico" />
<p className="ml-1 font-bold text-xl text-inherit">
Powered by EVRAZ
</p>
</NavbarBrand>
<NavbarItem className="mx-auto">
<Link color="foreground" to="#">
Features
</Link>
</NavbarItem>
<NavbarItem isActive>
<Link to="#" aria-current="page">
Customers
</Link>
</NavbarItem>
<NavbarItem>
<Link color="foreground" to="#">
Integrations
</Link>
</NavbarItem>
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem className="hidden lg:flex">
<Link to="#">Login</Link>
</NavbarItem>
<NavbarItem>
<Button as={Link} color="primary" to="#" variant="flat">
Sign Up
</Button>
</NavbarItem>
</NavbarContent>
<NavbarMenu>
{menuItems.map((item, index) => (
<NavbarMenuItem key={`${item}-${index}`}>
<Link
className="w-full"
color={
index === 2
? 'warning'
: index === menuItems.length - 1
? 'danger'
: 'foreground'
}
to="#"
>
{item}
</Link>
</NavbarMenuItem>
))}
</NavbarMenu>
</Navbar>
);
}

View File

@ -1,41 +1,44 @@
import type { LinksFunction } from "@remix-run/node";
import type { LinksFunction } from '@remix-run/node';
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import rootCss from "./root.css"
import { NextUIProvider } from "@nextui-org/react";
import NavbarCom from "./coms/navbar";
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from '@remix-run/react';
import rootCss from './root.css';
import { NextUIProvider } from '@nextui-org/react';
import NavbarCom from './coms/navbar';
export const links: LinksFunction = () => [
{ rel: "stylesheet", href: rootCss},
{ rel: "icon", href: "./favicon.ico"}
{ rel: 'stylesheet', href: rootCss },
{ rel: 'icon', href: './favicon.ico' },
];
export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body className="h-screen">
<NextUIProvider>
<NavbarCom />
<main className="h-content bg-background text-foreground flex justify-center items-center">
<Outlet />
</main>
<ScrollRestoration />
<Scripts />
<LiveReload />
</NextUIProvider>
</body>
</html>
);
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<Meta />
<Links />
</head>
<body className="h-screen">
<NextUIProvider>
<NavbarCom />
<main className="h-content bg-background text-foreground flex justify-center items-center">
<Outlet />
</main>
<ScrollRestoration />
<Scripts />
<LiveReload />
</NextUIProvider>
</body>
</html>
);
}

View File

@ -1,16 +1,12 @@
import type { LoaderFunctionArgs } from "@remix-run/node";
import { authenticator } from "~/services/auth.server";
import type { LoaderFunctionArgs } from '@remix-run/node';
import { authenticator } from '~/services/auth.server';
export async function loader({ request }: LoaderFunctionArgs) {
return await authenticator.isAuthenticated(request, {
failureRedirect: "/login",
failureRedirect: '/login',
});
};
}
export default function Index() {
return(
<>
</>
)
}
return <></>;
}

View File

@ -1,29 +1,42 @@
import { Button, Input } from "@nextui-org/react";
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
import { Form } from "@remix-run/react";
import { authenticator } from "~/services/auth.server";
import { Button, Input } from '@nextui-org/react';
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node';
import { Form } from '@remix-run/react';
import { authenticator } from '~/services/auth.server';
export async function loader({ request }: LoaderFunctionArgs) {
return await authenticator.isAuthenticated(request, {
successRedirect: "/",
successRedirect: '/',
});
};
}
export default function Auth() {
return(
<Form method="post">
<div id="auth" className="m-auto w-[300px] flex flex-col gap-6">
<Input name="login" color="primary" label="login" placeholder="Enter your login"/>
<Input name="password" type="password" color="primary" label="password" placeholder="Enter your password"/>
<Button type="submit" color="primary" > Login</Button>
</div>
</Form>
)
return (
<Form method="post">
<div id="auth" className="m-auto w-[300px] flex flex-col gap-6">
<Input
name="login"
color="primary"
label="login"
placeholder="Enter your login"
/>
<Input
name="password"
type="password"
color="primary"
label="password"
placeholder="Enter your password"
/>
<Button type="submit" color="primary">
{' '}
Login
</Button>
</div>
</Form>
);
}
export async function action({ request }: ActionFunctionArgs) {
return await authenticator.authenticate("user-auth", request, {
successRedirect: "/",
failureRedirect: "/login",
return await authenticator.authenticate('user-auth', request, {
successRedirect: '/',
failureRedirect: '/login',
});
};
}

View File

@ -1,29 +1,42 @@
import { Button, Input } from "@nextui-org/react";
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
import { Form } from "@remix-run/react";
import { authenticator } from "~/services/auth.server";
import { Button, Input } from '@nextui-org/react';
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node';
import { Form } from '@remix-run/react';
import { authenticator } from '~/services/auth.server';
export async function loader({ request }: LoaderFunctionArgs) {
return await authenticator.isAuthenticated(request, {
successRedirect: "/",
successRedirect: '/',
});
};
}
export default function Login() {
return(
<Form method="post">
<div id="login" className="m-auto w-[300px] flex flex-col gap-6">
<Input name="login" color="primary" label="login" placeholder="Enter your login"/>
<Input name="password" type="password" color="primary" label="password" placeholder="Enter your password"/>
<Button type="submit" color="primary" > Login</Button>
</div>
</Form>
)
return (
<Form method="post">
<div id="login" className="m-auto w-[300px] flex flex-col gap-6">
<Input
name="login"
color="primary"
label="login"
placeholder="Enter your login"
/>
<Input
name="password"
type="password"
color="primary"
label="password"
placeholder="Enter your password"
/>
<Button type="submit" color="primary">
{' '}
Login
</Button>
</div>
</Form>
);
}
export async function action({ request }: ActionFunctionArgs) {
return await authenticator.authenticate("user-login", request, {
successRedirect: "/",
failureRedirect: "/login",
return await authenticator.authenticate('user-login', request, {
successRedirect: '/',
failureRedirect: '/login',
});
};
}

View File

@ -1,11 +1,11 @@
import { Authenticator } from "remix-auth";
import { sessionStorage } from "~/services/session.server";
import { FormStrategy } from "remix-auth-form";
import bcrypt from "bcrypt";
import { Authenticator } from 'remix-auth';
import { sessionStorage } from '~/services/session.server';
import { FormStrategy } from 'remix-auth-form';
import bcrypt from 'bcrypt';
interface User{
login: string,
password: string,
interface User {
login: string;
password: string;
}
export let authenticator = new Authenticator<User>(sessionStorage);
@ -13,33 +13,35 @@ const saltRounds = 9;
authenticator.use(
new FormStrategy(async ({ form, context }) => {
let username = <string>form.get("login");
let password = <string>form.get("password");
let username = <string>form.get('login');
let password = <string>form.get('password');
const user = { login: 'null', password: 'null' };
const user = {login: "null", password: "null"};
return user;
}), "user-login"
);
}),
'user-login',
);
authenticator.use(
new FormStrategy(async ({ form, context }) => {
let username = <string>form.get("login");
let password = <string>form.get("password");
let username = <string>form.get('login');
let password = <string>form.get('password');
let hashedPassword = "";
await bcrypt.hash(password, saltRounds, (err, hash) => {
if (err) {
throw err;
let hashedPassword = '';
await bcrypt.hash(password, saltRounds, (error, hash) => {
if (error) {
throw error;
}
hashedPassword = hash;
});
if (!hashedPassword) {
throw "";
throw '';
}
const user = {login: "null", password: "null"};
return user;
}), "user-auth"
);
const user = { login: 'null', password: 'null' };
return user;
}),
'user-auth',
);

View File

@ -1,14 +1,14 @@
import { createCookieSessionStorage } from "@remix-run/node";
import { createCookieSessionStorage } from '@remix-run/node';
export let sessionStorage = createCookieSessionStorage({
cookie: {
name: "_session",
sameSite: "lax",
path: "/",
httpOnly: true,
secrets: ["s3cr3t"],
secure: process.env.NODE_ENV === "production",
name: '_session',
sameSite: 'lax',
path: '/',
httpOnly: true,
secrets: ['s3cr3t'],
secure: process.env.NODE_ENV === 'production',
},
});
export let { getSession, commitSession, destroySession } = sessionStorage;
});
export let { getSession, commitSession, destroySession } = sessionStorage;

1
src/database/database.ts Normal file
View File

@ -0,0 +1 @@
class Database {}

View File

@ -1,8 +1,23 @@
generator client {
provider = "prisma-client-js"
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
provider = "sqlite"
url = env("DATABASE_URL")
}
model Credentials {
id Int @id @default(autoincrement())
login String @unique
password String
worker Worker?
}
model Worker {
id Int @id @default(autoincrement())
credential Credentials @relation(fields: [credentialId],references: [id])
credentialId Int @unique
}

View File

@ -1,50 +1,50 @@
/** @type {import('tailwindcss').Config} */
import colors from "tailwindcss/colors";
import { nextui } from "@nextui-org/react";
import colors from 'tailwindcss/colors';
import { nextui } from '@nextui-org/react';
export const navbarHeight = "65px";
export const navbarHeight = '65px';
export default {
content: [
"./src/app/**/*.{js,jsx,ts,tsx}",
"./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
height: {
"navbar": navbarHeight,
"content": `calc(100vh - ${navbarHeight})`,
}
content: [
'./src/app/**/*.{js,jsx,ts,tsx}',
'./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
height: {
navbar: navbarHeight,
content: `calc(100vh - ${navbarHeight})`,
},
},
},
},
darkMode: "class",
plugins: [nextui({
defaultTheme: "light",
defaultExtendTheme: "light",
themes: {
light: {
colors: {
primary: {
...colors.orange,
DEFAULT: colors.orange[500],
},
secondary: {
...colors.gray,
DEFAULT: colors.gray[500],
},
warning: {
...colors.red,
foreground: colors.white,
DEFAULT: colors.red[500],
}
},
},
dark: {
colors: {
},
},
}
})],
}
darkMode: 'class',
plugins: [
nextui({
defaultTheme: 'light',
defaultExtendTheme: 'light',
themes: {
light: {
colors: {
primary: {
...colors.orange,
DEFAULT: colors.orange[500],
},
secondary: {
...colors.gray,
DEFAULT: colors.gray[500],
},
warning: {
...colors.red,
foreground: colors.white,
DEFAULT: colors.red[500],
},
},
},
dark: {
colors: {},
},
},
}),
],
};