mirror of
https://github.com/sern-handler/automata
synced 2026-06-06 01:16:51 +00:00
feat: login wall, bye yarn pnp
This commit is contained in:
2090
.pnp.loader.mjs
generated
2090
.pnp.loader.mjs
generated
File diff suppressed because it is too large
Load Diff
@@ -5,4 +5,5 @@ packageExtensions:
|
||||
"drizzle-orm": "*"
|
||||
"@drizzle-team/studio@*":
|
||||
dependencies:
|
||||
"drizzle-orm": "*"
|
||||
"drizzle-orm": "*"
|
||||
nodeLinker: node-modules
|
||||
@@ -26,7 +26,7 @@ const feedbackRateLimit = rateLimit({
|
||||
})
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.send('insert webserver here')
|
||||
res.send('hi this is the api what did you even expect')
|
||||
})
|
||||
|
||||
app.post('/wh/updateDocsJson', async (req, res) => {
|
||||
|
||||
4
apps/database/dist/index.d.ts
vendored
4
apps/database/dist/index.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
import 'dotenv/config';
|
||||
import * as schema from '../dist/schema.js';
|
||||
declare const _default: import("drizzle-orm/postgres-js").PostgresJsDatabase<typeof schema>;
|
||||
export default _default;
|
||||
6
apps/database/dist/index.js
vendored
6
apps/database/dist/index.js
vendored
@@ -1,6 +0,0 @@
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import 'dotenv/config';
|
||||
import * as schema from '../dist/schema.js';
|
||||
const client = postgres(process.env.DATABASE_URL);
|
||||
export default drizzle(client, { schema });
|
||||
1
apps/database/dist/migrations.d.ts
vendored
1
apps/database/dist/migrations.d.ts
vendored
@@ -1 +0,0 @@
|
||||
import 'dotenv/config';
|
||||
15
apps/database/dist/migrations.js
vendored
15
apps/database/dist/migrations.js
vendored
@@ -1,15 +0,0 @@
|
||||
import { drizzle } from "drizzle-orm/postgres-js/driver";
|
||||
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
||||
import postgres from "postgres";
|
||||
import 'dotenv/config';
|
||||
// this will automatically run needed migrations on the database
|
||||
const migrationClient = postgres(process.env.DATABASE_URL, { max: 1 });
|
||||
migrate(drizzle(migrationClient), { migrationsFolder: "./drizzle" })
|
||||
.then(() => {
|
||||
console.log("Migrations complete!");
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Migrations failed!", err);
|
||||
process.exit(1);
|
||||
});
|
||||
347
apps/database/dist/schema.d.ts
vendored
347
apps/database/dist/schema.d.ts
vendored
@@ -1,347 +0,0 @@
|
||||
export declare const guideFeedback: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
||||
name: "guideFeedback";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "id";
|
||||
tableName: "guideFeedback";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
feedback: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "feedback";
|
||||
tableName: "guideFeedback";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
route: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "route";
|
||||
tableName: "guideFeedback";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
inputText: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "inputText";
|
||||
tableName: "guideFeedback";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
};
|
||||
dialect: "pg";
|
||||
}>;
|
||||
export declare const users: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
||||
name: "user";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "id";
|
||||
tableName: "user";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
name: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "name";
|
||||
tableName: "user";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
email: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "email";
|
||||
tableName: "user";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
emailVerified: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "emailVerified";
|
||||
tableName: "user";
|
||||
dataType: "date";
|
||||
columnType: "PgTimestamp";
|
||||
data: Date;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
image: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "image";
|
||||
tableName: "user";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
};
|
||||
dialect: "pg";
|
||||
}>;
|
||||
export declare const accounts: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
||||
name: "account";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
userId: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "userId";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
type: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "type";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: "email" | "oidc" | "oauth";
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
provider: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "provider";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
providerAccountId: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "providerAccountId";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
refresh_token: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "refresh_token";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
access_token: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "access_token";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
expires_at: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "expires_at";
|
||||
tableName: "account";
|
||||
dataType: "number";
|
||||
columnType: "PgInteger";
|
||||
data: number;
|
||||
driverParam: string | number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
token_type: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "token_type";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
scope: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "scope";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
id_token: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "id_token";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
session_state: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "session_state";
|
||||
tableName: "account";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
};
|
||||
dialect: "pg";
|
||||
}>;
|
||||
export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
||||
name: "session";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
sessionToken: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "sessionToken";
|
||||
tableName: "session";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
userId: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "userId";
|
||||
tableName: "session";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
expires: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "expires";
|
||||
tableName: "session";
|
||||
dataType: "date";
|
||||
columnType: "PgTimestamp";
|
||||
data: Date;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
};
|
||||
dialect: "pg";
|
||||
}>;
|
||||
export declare const verificationTokens: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
||||
name: "verificationToken";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
identifier: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "identifier";
|
||||
tableName: "verificationToken";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
token: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "token";
|
||||
tableName: "verificationToken";
|
||||
dataType: "string";
|
||||
columnType: "PgText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
expires: import("drizzle-orm/pg-core").PgColumn<{
|
||||
name: "expires";
|
||||
tableName: "verificationToken";
|
||||
dataType: "date";
|
||||
columnType: "PgTimestamp";
|
||||
data: Date;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
}, {}, {}>;
|
||||
};
|
||||
dialect: "pg";
|
||||
}>;
|
||||
47
apps/database/dist/schema.js
vendored
47
apps/database/dist/schema.js
vendored
@@ -1,47 +0,0 @@
|
||||
import { timestamp, pgTable, text, primaryKey, integer, } from "drizzle-orm/pg-core";
|
||||
// automata schemas
|
||||
export const guideFeedback = pgTable("guideFeedback", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
feedback: text("feedback").notNull(),
|
||||
route: text("route").notNull(),
|
||||
inputText: text("inputText"),
|
||||
});
|
||||
// next-auth schema
|
||||
export const users = pgTable("user", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
name: text("name"),
|
||||
email: text("email").notNull(),
|
||||
emailVerified: timestamp("emailVerified", { mode: "date" }),
|
||||
image: text("image"),
|
||||
});
|
||||
export const accounts = pgTable("account", {
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
type: text("type").$type().notNull(),
|
||||
provider: text("provider").notNull(),
|
||||
providerAccountId: text("providerAccountId").notNull(),
|
||||
refresh_token: text("refresh_token"),
|
||||
access_token: text("access_token"),
|
||||
expires_at: integer("expires_at"),
|
||||
token_type: text("token_type"),
|
||||
scope: text("scope"),
|
||||
id_token: text("id_token"),
|
||||
session_state: text("session_state"),
|
||||
}, (account) => ({
|
||||
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
||||
}));
|
||||
export const sessions = pgTable("session", {
|
||||
sessionToken: text("sessionToken").notNull().primaryKey(),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
});
|
||||
export const verificationTokens = pgTable("verificationToken", {
|
||||
identifier: text("identifier").notNull(),
|
||||
token: text("token").notNull(),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
}, (vt) => ({
|
||||
compoundKey: primaryKey(vt.identifier, vt.token),
|
||||
}));
|
||||
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "tsc-watch --preserveWatchOutput",
|
||||
"migrate": "tsc && node dist/migrations.js",
|
||||
"migrate": "node dist/migrations.js",
|
||||
"generateMigrations": "drizzle-kit generate:pg --schema ./src/schema.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
|
||||
@@ -11,14 +11,22 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/drizzle-adapter": "^0.3.6",
|
||||
"@babel/runtime": "^7.23.7",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/material": "^5.15.2",
|
||||
"@mui/material-nextjs": "^5.15.0",
|
||||
"@planetscale/database": "^1.11.0",
|
||||
"@t3-oss/env-nextjs": "^0.7.1",
|
||||
"database": "1.0.0",
|
||||
"drizzle-orm": "^0.29.1",
|
||||
"next": "^14.0.3",
|
||||
"next": "^14.0.4",
|
||||
"next-auth": "^4.24.5",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"swr": "^2.2.4",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
|
||||
const config = {
|
||||
plugins: ["prettier-plugin-tailwindcss"],
|
||||
|
||||
useTabs: true,
|
||||
tabWidth: 2
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
BIN
apps/frontend/public/croppedlogo.png
Normal file
BIN
apps/frontend/public/croppedlogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -1,11 +1,13 @@
|
||||
import "~/styles/globals.css";
|
||||
import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
|
||||
import { Roboto } from "next/font/google";
|
||||
import { StyledEngineProvider } from '@mui/material/styles';
|
||||
import NextAuthProvider from "../components/NextAuthProvider";
|
||||
|
||||
import { Inter } from "next/font/google";
|
||||
import NextAuthProvider from "./NextAuthProvider";
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
const roboto = Roboto({
|
||||
weight: ['400'],
|
||||
variable: '--font-sans',
|
||||
subsets: ['latin']
|
||||
});
|
||||
|
||||
export const metadata = {
|
||||
@@ -21,9 +23,13 @@ export default function RootLayout({
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={`font-sans ${inter.variable}`}>
|
||||
<body className={`font-sans ${roboto.variable}`}>
|
||||
<NextAuthProvider>
|
||||
{children}
|
||||
<AppRouterCacheProvider options={{ enableCssLayer: true }}>
|
||||
<StyledEngineProvider injectFirst>
|
||||
{children}
|
||||
</StyledEngineProvider>
|
||||
</AppRouterCacheProvider>
|
||||
</NextAuthProvider>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,37 +1,19 @@
|
||||
import Link from "next/link";
|
||||
import { Container } from "@mui/material";
|
||||
import Authenticated from "~/components/HomePage/Authenticated";
|
||||
import Unauthenticated from "~/components/HomePage/Unauthenticated";
|
||||
import NavBar from "~/components/Layout/AppBar";
|
||||
import { getServerAuthSession } from "~/server/auth";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white">
|
||||
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
|
||||
<h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]">
|
||||
Create <span className="text-[hsl(280,100%,70%)]">T3</span> App
|
||||
</h1>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-8">
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/usage/first-steps"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">First Steps →</h3>
|
||||
<div className="text-lg">
|
||||
Just the basics - Everything you need to know to set up your
|
||||
database and authentication.
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/introduction"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">Documentation →</h3>
|
||||
<div className="text-lg">
|
||||
Learn more about Create T3 App, the libraries it uses, and how to
|
||||
deploy it.
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
export default async function HomePage() {
|
||||
const session = await getServerAuthSession();
|
||||
return session ?
|
||||
<div>
|
||||
<NavBar />
|
||||
{/*
|
||||
// @ts-expect-error https://github.com/mui/material-ui/issues/40370 */}
|
||||
<Container maxWidth="s">
|
||||
<Authenticated />
|
||||
</Container>
|
||||
</div>
|
||||
: <Unauthenticated />;
|
||||
}
|
||||
|
||||
7
apps/frontend/src/components/HomePage/Authenticated.tsx
Normal file
7
apps/frontend/src/components/HomePage/Authenticated.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
export default async function Authenticated() {
|
||||
return (
|
||||
<div>
|
||||
<p>hi</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
11
apps/frontend/src/components/HomePage/LoginButton.tsx
Normal file
11
apps/frontend/src/components/HomePage/LoginButton.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
import { Button } from "@mui/material";
|
||||
import { signIn } from "next-auth/react";
|
||||
|
||||
export default function LoginButton() {
|
||||
return (
|
||||
<Button variant="outlined" onClick={() => signIn()}>
|
||||
Login
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
22
apps/frontend/src/components/HomePage/Unauthenticated.tsx
Normal file
22
apps/frontend/src/components/HomePage/Unauthenticated.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import LoginButton from "./LoginButton";
|
||||
|
||||
export default async function Unauthenticated() {
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="absolute top-0 right-0 pt-4 pr-4">
|
||||
<LoginButton />
|
||||
</div>
|
||||
<div className="flex h-screen flex-col items-center justify-center gap-3">
|
||||
<h1 className="text-6xl">Hey!</h1>
|
||||
<p className="text-2xl">
|
||||
You just stomped on the frontend of sern Automata.
|
||||
</p>
|
||||
<p className="text-2xl">
|
||||
It's unfortunately WIP and for security purposes it's behind a login
|
||||
wall that only the devteam can access.
|
||||
</p>
|
||||
<p className="text-3xl">Sorry!</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
164
apps/frontend/src/components/Layout/AppBar.tsx
Normal file
164
apps/frontend/src/components/Layout/AppBar.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Box from '@mui/material/Box';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import { MdMenu } from 'react-icons/md';
|
||||
import Container from '@mui/material/Container';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import Button from '@mui/material/Button';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Logo from '../../../public/croppedlogo.png';
|
||||
import Image from 'next/image';
|
||||
import { signOut } from 'next-auth/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useSession } from "next-auth/react"
|
||||
|
||||
const pages = ['Home'];
|
||||
const settings = ['Account', 'Logout'];
|
||||
|
||||
export default function NavBar() {
|
||||
const { data: session } = useSession()
|
||||
const router = useRouter();
|
||||
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null);
|
||||
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null);
|
||||
|
||||
const settingLinkHandler = (setting: string) => {
|
||||
switch (setting) {
|
||||
case 'Logout':
|
||||
return void signOut();
|
||||
case 'Account':
|
||||
return void router.push('/account');
|
||||
}
|
||||
}
|
||||
|
||||
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElNav(event.currentTarget);
|
||||
};
|
||||
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElUser(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseNavMenu = () => {
|
||||
setAnchorElNav(null);
|
||||
};
|
||||
|
||||
const handleCloseUserMenu = () => {
|
||||
setAnchorElUser(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='pb-2'>
|
||||
<AppBar position="static">
|
||||
<Container maxWidth="xl">
|
||||
<Toolbar disableGutters>
|
||||
<Image src={Logo} alt='logo' className='h-9 w-fit pr-5' />
|
||||
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
|
||||
<IconButton
|
||||
size="large"
|
||||
aria-label="account of current user"
|
||||
aria-controls="menu-appbar"
|
||||
aria-haspopup="true"
|
||||
onClick={handleOpenNavMenu}
|
||||
color="inherit"
|
||||
>
|
||||
<MdMenu />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorElNav}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
open={Boolean(anchorElNav)}
|
||||
onClose={handleCloseNavMenu}
|
||||
sx={{
|
||||
display: { xs: 'block', md: 'none' },
|
||||
}}
|
||||
>
|
||||
{pages.map((page) => (
|
||||
<MenuItem key={page} onClick={handleCloseNavMenu}>
|
||||
<Typography textAlign="center">{page}</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</Box>
|
||||
<Typography
|
||||
variant="h5"
|
||||
noWrap
|
||||
component="a"
|
||||
href="#app-bar-with-responsive-menu"
|
||||
sx={{
|
||||
mr: 2,
|
||||
display: { xs: 'flex', md: 'none' },
|
||||
flexGrow: 1,
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '.3rem',
|
||||
color: 'inherit',
|
||||
textDecoration: 'none',
|
||||
}}
|
||||
>
|
||||
AUTOMATA
|
||||
</Typography>
|
||||
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
|
||||
{pages.map((page) => (
|
||||
<Button
|
||||
key={page}
|
||||
onClick={handleCloseNavMenu}
|
||||
sx={{ my: 2, color: 'white', display: 'block' }}
|
||||
>
|
||||
{page}
|
||||
</Button>
|
||||
))}
|
||||
</Box>
|
||||
|
||||
<Box sx={{ flexGrow: 0 }}>
|
||||
<Tooltip title="Open settings">
|
||||
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
|
||||
<Avatar alt={'Account'} src={session ? session.user.image! : '...'} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
sx={{ mt: '45px' }}
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorElUser}
|
||||
anchorOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
open={Boolean(anchorElUser)}
|
||||
onClose={handleCloseUserMenu}
|
||||
>
|
||||
{settings.map((setting) => (
|
||||
<MenuItem key={setting} onClick={() => {
|
||||
handleCloseUserMenu();
|
||||
settingLinkHandler(setting);
|
||||
}}>
|
||||
<Typography textAlign="center">{setting}</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</Container>
|
||||
</AppBar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { SessionProvider } from 'next-auth/react';
|
||||
import { ReactNode } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export default function NextAuthProvider({
|
||||
children,
|
||||
@@ -43,6 +43,14 @@ export const authOptions: NextAuthOptions = {
|
||||
id: user.id,
|
||||
},
|
||||
}),
|
||||
signIn(params) {
|
||||
const allowedUsers = ['SrIzan10', 'jacoobes', 'Murtarxx', 'EvolutionX-10']
|
||||
if (!allowedUsers.includes(params.user.name!)) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
},
|
||||
},
|
||||
adapter: PostgresJsDrizzleAdapter(db),
|
||||
providers: [
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/*
|
||||
deactivating the preflight plugin creates an ugly border
|
||||
on all sides of the screen, so these css values removes them
|
||||
*/
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
figure,
|
||||
blockquote,
|
||||
fieldset,
|
||||
legend {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -11,4 +11,7 @@ export default {
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
corePlugins: {
|
||||
preflight: false
|
||||
}
|
||||
} satisfies Config;
|
||||
|
||||
@@ -10,4 +10,4 @@ services:
|
||||
volumes:
|
||||
- ./data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
- 5431:5432
|
||||
@@ -5,6 +5,7 @@
|
||||
"repository": "https://github.com/sern-handler/automata.git",
|
||||
"author": "Izan Gil <66965250+SrIzan10@users.noreply.github.com>",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"workspaces": [
|
||||
"apps/*"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user