Update Bridge file layout

This commit is contained in:
Darren Clarke 2024-04-23 13:36:51 +02:00
parent 2c43e81436
commit b0fb643b6a
47 changed files with 2488 additions and 2087 deletions

View file

@ -0,0 +1,14 @@
import { Metadata } from "next";
import { getSession } from "next-auth/react";
import { Login } from "@/app/_components/Login";
export const dynamic = "force-dynamic";
export const metadata: Metadata = {
title: "Login",
};
export default async function Page() {
const session = await getSession();
return <Login session={session} />;
}

View file

@ -1,10 +1,14 @@
"use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro"; import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "ui"; import { List } from "@/app/_components/List";
// import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic"; type FacebookBotsListProps = {
rows: any[];
};
export default async function Page() { export const FacebookBotsList: FC<FacebookBotsListProps> = ({ rows }) => {
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: "id", field: "id",
@ -32,14 +36,12 @@ export default async function Page() {
}, },
]; ];
const rows: any = []; // await db.selectFrom("WhatsAppBot").selectAll().execute();
return ( return (
<List <List
title="Whatsapp Bots" title="Facebook Bots"
entity="facebook"
rows={rows} rows={rows}
columns={columns} columns={columns}
onRowClick={() => {}}
/> />
); );
} };

View file

@ -0,0 +1,10 @@
import { FacebookBotsList } from "./_components/FacebookBotsList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("FacebookBot").selectAll().execute();
return <FacebookBotsList rows={rows} />;
}

View file

@ -0,0 +1,9 @@
import { InternalLayout } from "@/app/_components/InternalLayout";
export default function Layout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return <InternalLayout>{children}</InternalLayout>;
}

View file

@ -1,9 +1,14 @@
"use client"; "use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro"; import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "ui"; import { List } from "@/app/_components/List";
export default function Page() { type SignalBotsListProps = {
rows: any[];
};
export const SignalBotsList: FC<SignalBotsListProps> = ({ rows }) => {
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: "id", field: "id",
@ -31,14 +36,7 @@ export default function Page() {
}, },
]; ];
const rows = [ return (
{ <List title="Signal Bots" entity="signal" rows={rows} columns={columns} />
id: 10, );
phoneNumber: "1234567890", };
createdAt: new Date(),
updatedAt: new Date(),
},
];
return <List title="Voice bots" rows={rows} columns={columns} />;
}

View file

@ -0,0 +1,10 @@
import { SignalBotsList } from "./_components/SignalBotsList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("SignalBot").selectAll().execute();
return <SignalBotsList rows={rows} />;
}

View file

@ -0,0 +1,31 @@
"use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "@/app/_components/List";
type UsersListProps = {
rows: any[];
};
export const UsersList: FC<UsersListProps> = ({ rows }) => {
const columns: GridColDef[] = [
{
field: "name",
headerName: "Name",
flex: 2,
},
{
field: "email",
headerName: "Email",
flex: 2,
},
{
field: "emailVerified",
headerName: "Verified",
flex: 1,
},
];
return <List title="Users" entity="users" rows={rows} columns={columns} />;
};

View file

@ -0,0 +1,11 @@
import { UsersList } from "./_components/UsersList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("User").selectAll().execute();
console.log(rows);
return <UsersList rows={rows} />;
}

View file

@ -1,9 +1,14 @@
"use client"; "use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro"; import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "ui"; import { List } from "@/app/_components/List";
export default function Page() { type VoiceBotsListProps = {
rows: any[];
};
export const VoiceBotsList: FC<VoiceBotsListProps> = ({ rows }) => {
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: "id", field: "id",
@ -31,14 +36,5 @@ export default function Page() {
}, },
]; ];
const rows = [ return <List title="Voice Bots" entity="voice" rows={rows} columns={columns} />;
{ };
id: 10,
phoneNumber: "1234567890",
createdAt: new Date(),
updatedAt: new Date(),
},
];
return <List title="Facebook" rows={rows} columns={columns} />;
}

View file

@ -0,0 +1,10 @@
import { VoiceBotsList } from "./_components/VoiceBotsList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("VoiceLine").selectAll().execute();
return <VoiceBotsList rows={rows} />;
}

View file

@ -1,9 +1,14 @@
"use client"; "use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro"; import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "ui"; import { List } from "@/app/_components/List";
export default function Page() { type WebhooksListProps = {
rows: any[];
};
export const WebhooksList: FC<WebhooksListProps> = ({ rows }) => {
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: "id", field: "id",
@ -31,14 +36,7 @@ export default function Page() {
}, },
]; ];
const rows = [ return (
{ <List title="Webhooks" entity="webhooks" rows={rows} columns={columns} />
id: 10, );
phoneNumber: "1234567890", };
createdAt: new Date(),
updatedAt: new Date(),
},
];
return <List title="Users" rows={rows} columns={columns} />;
}

View file

@ -0,0 +1,11 @@
import { WebhooksList } from "./_components/WebhooksList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("Webhook").selectAll().execute();
console.log(rows);
return <WebhooksList rows={rows} />;
}

View file

@ -1,9 +1,14 @@
"use client"; "use client";
import { FC } from "react";
import { GridColDef } from "@mui/x-data-grid-pro"; import { GridColDef } from "@mui/x-data-grid-pro";
import { List } from "ui"; import { List } from "@/app/_components/List";
export default function Page() { type WhatsappListProps = {
rows: any[];
};
export const WhatsappList: FC<WhatsappListProps> = ({ rows }) => {
const columns: GridColDef[] = [ const columns: GridColDef[] = [
{ {
field: "id", field: "id",
@ -31,14 +36,12 @@ export default function Page() {
}, },
]; ];
const rows = [ return (
{ <List
id: 10, title="WhatsApp Bots"
phoneNumber: "1234567890", entity="whatsapp"
createdAt: new Date(), rows={rows}
updatedAt: new Date(), columns={columns}
}, />
]; );
};
return <List title="Signal Bots" rows={rows} columns={columns} />;
}

View file

@ -0,0 +1,11 @@
import { WhatsappList } from "./_components/WhatsappList";
import { db } from "@/app/_lib/database";
export const dynamic = "force-dynamic";
export default async function Page() {
const rows = await db.selectFrom("WhatsappBot").selectAll().execute();
console.log(rows);
return <WhatsappList rows={rows} />;
}

View file

@ -0,0 +1 @@
"use server";

View file

@ -1,7 +1,7 @@
"use client"; "use client";
import { FC } from "react"; import { FC } from "react";
import { Grid, Box } from "@mui/material"; import { Grid, Box, Dialog } from "@mui/material";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { typography } from "@/app/_styles/theme"; import { typography } from "@/app/_styles/theme";
@ -16,15 +16,20 @@ export const Detail: FC<DetailProps> = ({ title, entity, children }) => {
const { h3 } = typography; const { h3 } = typography;
return ( return (
<Dialog
open={true}
onClose={() => router.push(`/${entity}`)}
fullScreen
sx={{ backgroundColor: "#ddd" }}
>
<Box sx={{ height: "100vh", backgroundColor: "#ddd", p: 3 }}> <Box sx={{ height: "100vh", backgroundColor: "#ddd", p: 3 }}>
<Grid container direction="column"> <Grid container direction="column">
<Grid item> <Grid item>
<Box sx={h3}>{title}</Box> <Box sx={h3}>{title}</Box>
</Grid> </Grid>
<Grid item> <Grid item>{children}</Grid>
{children}
</Grid>
</Grid> </Grid>
</Box> </Box>
</Dialog>
); );
}; };

View file

@ -2,14 +2,10 @@
import { FC, PropsWithChildren, useState } from "react"; import { FC, PropsWithChildren, useState } from "react";
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
import { Sidebar } from "./Sidebar";
import { CssBaseline } from "@mui/material"; import { CssBaseline } from "@mui/material";
import { css, Global } from "@emotion/react"; import { css, Global } from "@emotion/react";
import { fonts } from "@/app/_styles/theme"; import { fonts } from "@/app/_styles/theme";
import { Sidebar } from "./Sidebar";
type LayoutProps = PropsWithChildren<{
docs?: any;
}>;
export const InternalLayout: FC<PropsWithChildren> = ({ children }) => { export const InternalLayout: FC<PropsWithChildren> = ({ children }) => {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@ -28,7 +24,7 @@ export const InternalLayout: FC<PropsWithChildren> = ({ children }) => {
<Sidebar open={open} setOpen={setOpen} /> <Sidebar open={open} setOpen={setOpen} />
<Grid <Grid
item item
sx={{ ml: open ? "270px" : "100px", width: "100%", height: "100vh" }} sx={{ ml: open ? "270px" : "70px", width: "100%", height: "100vh" }}
> >
{children as any} {children as any}
</Grid> </Grid>

View file

@ -1,10 +1,9 @@
"use client"; "use client";
import { FC } from "react"; import { FC } from "react";
import { Grid, Box } from "@mui/material"; import { GridColDef } from "@mui/x-data-grid-pro";
import { DataGridPro, GridColDef } from "@mui/x-data-grid-pro";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { typography } from "@/app/_styles/theme"; import { List as InternalList } from "ui";
interface ListProps { interface ListProps {
title: string; title: string;
@ -15,72 +14,17 @@ interface ListProps {
export const List: FC<ListProps> = ({ title, entity, rows, columns }) => { export const List: FC<ListProps> = ({ title, entity, rows, columns }) => {
const router = useRouter(); const router = useRouter();
const { h3 } = typography;
const onRowClick = (id: string) => { const onRowClick = (id: string) => {
router.push(`/${entity}/${id}`); router.push(`/${entity}/${id}`);
}; };
return ( return (
<Box sx={{ height: "100vh", backgroundColor: "#ddd", p: 3 }}> <InternalList
<Grid container direction="column"> title={title}
<Grid item>
<Box sx={h3}>{title}</Box>
</Grid>
<Grid item>
<Box
sx={{
backgroundColor: "#ddd",
border: 0,
width: "100%",
height: "100vh",
".MuiDataGrid-row": {
cursor: "pointer",
"&:hover": {
backgroundColor: "#1982fc33 !important",
fontWeight: "bold",
},
},
".MuiDataGrid-row:nth-of-type(1n)": {
backgroundColor: "#f3f3f3",
},
".MuiDataGrid-row:nth-of-type(2n)": {
backgroundColor: "#fff",
},
".MuiDataGrid-columnHeaderTitle": {
color: "#333",
fontWeight: "bold",
fontSize: 11,
margin: "0 auto",
},
".MuiDataGrid-columnHeader": {
backgroundColor: "#ccc",
border: 0,
borderBottom: "3px solid #ddd",
},
}}
>
<DataGridPro
rows={rows} rows={rows}
columns={columns} columns={columns}
density="compact" onRowClick={onRowClick}
pagination
initialState={{
pagination: { paginationModel: { pageSize: 25 } },
}}
pageSizeOptions={[5, 10, 25]}
paginationMode="client"
sx={{ height: "100vh" }}
// rowBuffer={30}
rowHeight={46}
scrollbarSize={0}
disableVirtualization
disableColumnMenu
onRowClick={(row: any) => onRowClick(row.id)}
/> />
</Box>
</Grid>
</Grid>
</Box>
); );
}; };

View file

@ -0,0 +1,184 @@
"use client";
import { FC, useState } from "react";
import {
Box,
Grid,
Container,
IconButton,
Typography,
TextField,
} from "@mui/material";
import {
Apple as AppleIcon,
Google as GoogleIcon,
Key as KeyIcon,
} from "@mui/icons-material";
import { signIn } from "next-auth/react";
import Image from "next/image";
import LinkLogo from "@/app/../public/link-logo-small.png";
import { colors } from "@/app/_styles/theme";
import { useSearchParams } from "next/navigation";
type LoginProps = {
session: any;
};
export const Login: FC<LoginProps> = ({ session }) => {
const origin =
typeof window !== "undefined" && window.location.origin
? window.location.origin
: "";
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const params = useSearchParams();
const error = params.get("error");
const { darkGray, cdrLinkOrange, white } = colors;
const buttonStyles = {
borderRadius: 500,
width: "100%",
fontSize: "16px",
fontWeight: "bold",
backgroundColor: white,
"&:hover": {
color: white,
backgroundColor: cdrLinkOrange,
},
};
const fieldStyles = {
"& label.Mui-focused": {
color: cdrLinkOrange,
},
"& .MuiInput-underline:after": {
borderBottomColor: cdrLinkOrange,
},
"& .MuiFilledInput-underline:after": {
borderBottomColor: cdrLinkOrange,
},
"& .MuiOutlinedInput-root": {
"&.Mui-focused fieldset": {
borderColor: cdrLinkOrange,
},
},
};
return (
<Box sx={{ backgroundColor: darkGray, height: "100vh" }}>
<Container maxWidth="md" sx={{ p: 10 }}>
<Grid container spacing={2} direction="column" alignItems="center">
<Grid
item
container
direction="row"
justifyContent="center"
alignItems="center"
>
<Grid item>
<Box
sx={{
width: "70px",
height: "70px",
margin: "0 auto",
}}
>
<Image
src={LinkLogo}
alt="Link logo"
width={70}
height={70}
style={{
objectFit: "cover",
filter: "grayscale(100) brightness(100)",
}}
/>
</Box>
</Grid>
<Grid item>
<Typography
variant="h2"
sx={{
fontSize: 36,
color: "white",
fontWeight: 700,
mt: 1,
ml: 0.5,
fontFamily: "Poppins",
}}
>
CDR Bridge
</Typography>
</Grid>
</Grid>
<Grid item sx={{ width: "100%" }}>
{!session ? (
<Container
maxWidth="xs"
sx={{
p: 3,
mt: 3,
}}
>
<Grid
container
spacing={3}
direction="column"
alignItems="center"
>
{error ? (
<Grid item sx={{ width: "100%" }}>
<Box sx={{ backgroundColor: "red", p: 3 }}>
<Typography
variant="body1"
sx={{
fontSize: 18,
color: "white",
textAlign: "center",
}}
>
{`${error} error`}
</Typography>
</Box>
</Grid>
) : null}
<Grid item sx={{ width: "100%" }}>
<IconButton
sx={buttonStyles}
onClick={() =>
signIn("google", {
callbackUrl: `${origin}`,
})
}
>
<GoogleIcon sx={{ mr: 1 }} />
Sign in with Google
</IconButton>
</Grid>
<Grid item sx={{ width: "100%" }}>
<IconButton
aria-label="Sign in with Apple"
sx={buttonStyles}
onClick={() =>
signIn("apple", {
callbackUrl: `${window.location.origin}`,
})
}
>
<AppleIcon sx={{ mr: 1 }} />
Sign in with Apple
</IconButton>
</Grid>
</Grid>
</Container>
) : null}
{session ? (
<Box component="h4">
{` ${session.user.name ?? session.user.email}.`}
</Box>
) : null}
</Grid>
</Grid>
</Container>
</Box>
);
};

View file

@ -19,6 +19,7 @@ import {
PermPhoneMsg as PhoneIcon, PermPhoneMsg as PhoneIcon,
WhatsApp as WhatsAppIcon, WhatsApp as WhatsAppIcon,
Facebook as FacebookIcon, Facebook as FacebookIcon,
AirlineStops as AirlineStopsIcon,
} from "@mui/icons-material"; } from "@mui/icons-material";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
@ -28,7 +29,7 @@ import LinkLogo from "@/public/link-logo-small.png";
// import { useSession, signOut } from "next-auth/react"; // import { useSession, signOut } from "next-auth/react";
const openWidth = 270; const openWidth = 270;
const closedWidth = 100; const closedWidth = 70;
const MenuItem = ({ const MenuItem = ({
name, name,
@ -180,7 +181,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
<Box <Box
sx={{ sx={{
position: "absolute", position: "absolute",
top: 20, top: 24,
right: open ? -8 : -16, right: open ? -8 : -16,
color: "#1C75FD", color: "#1C75FD",
rotate: open ? "90deg" : "-90deg", rotate: open ? "90deg" : "-90deg",
@ -191,8 +192,8 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
> >
<ExpandCircleDownIcon <ExpandCircleDownIcon
sx={{ sx={{
width: 30, width: 24,
height: 30, height: 24,
background: "white", background: "white",
borderRadius: 500, borderRadius: 500,
}} }}
@ -308,7 +309,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
}} }}
> >
<MenuItem <MenuItem
name="Whatsapp" name="WhatsApp"
href="/whatsapp" href="/whatsapp"
selected={pathname.endsWith("/whatsapp")} selected={pathname.endsWith("/whatsapp")}
Icon={WhatsAppIcon} Icon={WhatsAppIcon}
@ -335,6 +336,13 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
Icon={PhoneIcon} Icon={PhoneIcon}
iconSize={20} iconSize={20}
/> />
<MenuItem
name="Webhooks"
href="/webhooks"
selected={pathname.startsWith("/webhooks")}
Icon={AirlineStopsIcon}
iconSize={20}
/>
<MenuItem <MenuItem
name="Users" name="Users"
href="/users" href="/users"

View file

@ -1,9 +1,8 @@
import NextAuth from "next-auth" import GoogleProvider from "next-auth/providers/google";
import GoogleProvider from "next-auth/providers/google" import { KyselyAdapter } from "@auth/kysely-adapter";
import { KyselyAdapter } from "@auth/kysely-adapter"
import { db } from "./database"; import { db } from "./database";
export const authOptions = NextAuth({ export const authOptions = {
// @ts-ignore // @ts-ignore
adapter: KyselyAdapter(db), adapter: KyselyAdapter(db),
providers: [ providers: [
@ -12,4 +11,7 @@ export const authOptions = NextAuth({
clientSecret: process.env.GOOGLE_CLIENT_SECRET!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}), }),
], ],
}) session: {
strategy: "jwt" as any,
},
};

View file

@ -53,7 +53,7 @@ export interface Database {
expires: Date; expires: Date;
}; };
WhatsAppBot: { WhatsappBot: {
id: GeneratedAlways<string>; id: GeneratedAlways<string>;
name: string; name: string;
phoneNumber: string; phoneNumber: string;
@ -70,7 +70,7 @@ export interface Database {
updatedAt: Date; updatedAt: Date;
}; };
VoiceBot: { VoiceLine: {
id: GeneratedAlways<string>; id: GeneratedAlways<string>;
name: string; name: string;
createdBy: string; createdBy: string;
@ -86,6 +86,14 @@ export interface Database {
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
}; };
Webhook: {
id: GeneratedAlways<string>;
name: string;
createdBy: string;
createdAt: Date;
updatedAt: Date;
};
} }
export const db = new KyselyAuth<Database>({ export const db = new KyselyAuth<Database>({

View file

@ -1,6 +1,7 @@
import NextAuth from "next-auth"; import NextAuth from "next-auth";
import { authOptions } from "@/app/_lib/authentication"; import { authOptions } from "@/app/_lib/authentication";
// @ts-expect-error
const handler = NextAuth(authOptions); const handler = NextAuth(authOptions);
export { handler as GET, handler as POST }; export { handler as GET, handler as POST };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,5 +1,4 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { InternalLayout } from "./_components/InternalLayout";
import { LicenseInfo } from "@mui/x-license"; import { LicenseInfo } from "@mui/x-license";
LicenseInfo.setLicenseKey( LicenseInfo.setLicenseKey(
@ -18,9 +17,7 @@ export default function RootLayout({
}>) { }>) {
return ( return (
<html lang="en"> <html lang="en">
<body> <body>{children}</body>
<InternalLayout>{children}</InternalLayout>
</body>
</html> </html>
); );
} }

View file

@ -1,230 +0,0 @@
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 6rem;
min-height: 100vh;
}
.description {
display: inherit;
justify-content: inherit;
align-items: inherit;
font-size: 0.85rem;
max-width: var(--max-width);
width: 100%;
z-index: 2;
font-family: var(--font-mono);
}
.description a {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
}
.description p {
position: relative;
margin: 0;
padding: 1rem;
background-color: rgba(var(--callout-rgb), 0.5);
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
border-radius: var(--border-radius);
}
.code {
font-weight: 700;
font-family: var(--font-mono);
}
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(25%, auto));
max-width: 100%;
width: var(--max-width);
}
.card {
padding: 1rem 1.2rem;
border-radius: var(--border-radius);
background: rgba(var(--card-rgb), 0);
border: 1px solid rgba(var(--card-border-rgb), 0);
transition: background 200ms, border 200ms;
}
.card span {
display: inline-block;
transition: transform 200ms;
}
.card h2 {
font-weight: 600;
margin-bottom: 0.7rem;
}
.card p {
margin: 0;
opacity: 0.6;
font-size: 0.9rem;
line-height: 1.5;
max-width: 30ch;
text-wrap: balance;
}
.center {
display: flex;
justify-content: center;
align-items: center;
position: relative;
padding: 4rem 0;
}
.center::before {
background: var(--secondary-glow);
border-radius: 50%;
width: 480px;
height: 360px;
margin-left: -400px;
}
.center::after {
background: var(--primary-glow);
width: 240px;
height: 180px;
z-index: -1;
}
.center::before,
.center::after {
content: "";
left: 50%;
position: absolute;
filter: blur(45px);
transform: translateZ(0);
}
.logo {
position: relative;
}
/* Enable hover only on non-touch devices */
@media (hover: hover) and (pointer: fine) {
.card:hover {
background: rgba(var(--card-rgb), 0.1);
border: 1px solid rgba(var(--card-border-rgb), 0.15);
}
.card:hover span {
transform: translateX(4px);
}
}
@media (prefers-reduced-motion) {
.card:hover span {
transform: none;
}
}
/* Mobile */
@media (max-width: 700px) {
.content {
padding: 4rem;
}
.grid {
grid-template-columns: 1fr;
margin-bottom: 120px;
max-width: 320px;
text-align: center;
}
.card {
padding: 1rem 2.5rem;
}
.card h2 {
margin-bottom: 0.5rem;
}
.center {
padding: 8rem 0 6rem;
}
.center::before {
transform: none;
height: 300px;
}
.description {
font-size: 0.8rem;
}
.description a {
padding: 1rem;
}
.description p,
.description div {
display: flex;
justify-content: center;
position: fixed;
width: 100%;
}
.description p {
align-items: center;
inset: 0 0 auto;
padding: 2rem 1rem 1.4rem;
border-radius: 0;
border: none;
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
background: linear-gradient(
to bottom,
rgba(var(--background-start-rgb), 1),
rgba(var(--callout-rgb), 0.5)
);
background-clip: padding-box;
backdrop-filter: blur(24px);
}
.description div {
align-items: flex-end;
pointer-events: none;
inset: auto 0 0;
padding: 2rem;
height: 200px;
background: linear-gradient(
to bottom,
transparent 0%,
rgb(var(--background-end-rgb)) 40%
);
z-index: 1;
}
}
/* Tablet and Smaller Desktop */
@media (min-width: 701px) and (max-width: 1120px) {
.grid {
grid-template-columns: repeat(2, 50%);
}
}
@media (prefers-color-scheme: dark) {
.vercelLogo {
filter: invert(1);
}
.logo {
filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
}
}
@keyframes rotate {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}

View file

@ -0,0 +1,24 @@
import { withAuth } from "next-auth/middleware";
export default withAuth({
pages: {
signIn: `/login`,
},
callbacks: {
authorized: ({ token }) => {
if (process.env.SETUP_MODE === "true") {
return true;
}
if (token?.email) {
return true;
}
return false;
},
},
});
export const config = {
matcher: ["/((?!ws|wss|api|_next/static|_next/image|favicon.ico).*)"],
};

View file

@ -1,9 +1,6 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
transpilePackages: ["ui"], transpilePackages: ["ui"],
experimental: {
instrumentationHook: true,
},
}; };
export default nextConfig; export default nextConfig;

3719
package-lock.json generated

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -17,7 +17,7 @@ export const List: FC<ListProps> = ({
title, title,
rows, rows,
columns, columns,
onRowClick = () => {}, onRowClick,
buttons, buttons,
}) => { }) => {
const { h3 } = typography; const { h3 } = typography;
@ -34,10 +34,11 @@ export const List: FC<ListProps> = ({
<Grid item> <Grid item>
<Box <Box
sx={{ sx={{
mt: 2,
backgroundColor: "#ddd", backgroundColor: "#ddd",
border: 0, border: 0,
width: "100%", width: "100%",
height: "100vh", height: "calc(100vh - 100px)",
".MuiDataGrid-row": { ".MuiDataGrid-row": {
cursor: "pointer", cursor: "pointer",
"&:hover": { "&:hover": {
@ -74,12 +75,12 @@ export const List: FC<ListProps> = ({
}} }}
pageSizeOptions={[5, 10, 25]} pageSizeOptions={[5, 10, 25]}
paginationMode="client" paginationMode="client"
sx={{ height: "100vh" }} sx={{ height: "100%" }}
rowHeight={46} rowHeight={46}
scrollbarSize={0} scrollbarSize={0}
disableVirtualization disableVirtualization
disableColumnMenu disableColumnMenu
onRowClick={(row: any) => onRowClick(row.id)} onRowClick={(row: any) => onRowClick?.(row.id)}
/> />
</Box> </Box>
</Grid> </Grid>

View file

@ -1,2 +1,8 @@
import { LicenseInfo } from "@mui/x-license";
LicenseInfo.setLicenseKey(
"7c9bf25d9e240f76e77cbf7d2ba58a23Tz02NjU4OCxFPTE3MTU4NjIzMzQ2ODgsUz1wcm8sTE09c3Vic2NyaXB0aW9uLEtWPTI=",
);
export { List } from "./components/List"; export { List } from "./components/List";
export { fonts, typography, colors } from "./styles/theme"; export { fonts, typography, colors } from "./styles/theme";

View file

@ -13,7 +13,7 @@ const playfair = Playfair_Display({
}); });
const poppins = Poppins({ const poppins = Poppins({
weight: ["400", "700"], weight: ["400", "600", "700"],
subsets: ["latin"], subsets: ["latin"],
display: "swap", display: "swap",
}); });
@ -70,7 +70,7 @@ export const typography: any = {
}, },
h3: { h3: {
fontFamily: poppins.style.fontFamily, fontFamily: poppins.style.fontFamily,
fontWeight: 400, fontWeight: 600,
fontSize: 27, fontSize: 27,
lineHeight: 1.1, lineHeight: 1.1,
margin: 0, margin: 0,

File diff suppressed because one or more lines are too long