This commit is contained in:
Darren Clarke 2023-07-18 12:26:57 +00:00
parent 7ca5f2d45a
commit f901f203b0
302 changed files with 9897 additions and 10332 deletions

View file

@ -8,14 +8,13 @@ WORKDIR ${APP_DIR}
COPY . .
RUN turbo prune --scope=@digiresilience/metamigo-frontend --docker
FROM base AS installer
ARG APP_DIR=/opt/metamigo-frontend
WORKDIR ${APP_DIR}
COPY .gitignore .gitignore
COPY --from=builder ${APP_DIR}/out/json/ .
COPY --from=builder ${APP_DIR}/out/package-lock.json ./package-lock.json
RUN npm ci --omit=dev
RUN npm i
COPY --from=builder ${APP_DIR}/out/full/ .
RUN npm i -g turbo

View file

@ -1,4 +1,6 @@
import { FC, useEffect } from "react";
"use client";
import { FC, useEffect, PropsWithChildren } from "react";
import { CircularProgress, Typography, Grid } from "@mui/material";
import { signIn, signOut, getSession } from "next-auth/react";
import { useLogin, useTranslate } from "react-admin";
@ -17,7 +19,7 @@ export const authProvider = {
checkError(e: any) {
if (e.graphQLErrors && e.graphQLErrors.length > 0) {
const permDenied = e.graphQLErrors.some((e: any) =>
e.message.match(/.*permission denied.*/)
e.message.match(/.*permission denied.*/),
);
if (permDenied)
// eslint-disable-next-line prefer-promise-reject-errors

View file

@ -1,7 +1,9 @@
"use client";
import { FC, PropsWithChildren, useEffect } from "react";
import { CircularProgress } from "@mui/material";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { useRouter } from "next/navigation";
export const Auth: FC<PropsWithChildren> = ({ children }) => {
const router = useRouter();

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable react/display-name */
import { forwardRef } from "react";
import useDigitInput, { InputAttributes } from "react-digit-input";

View file

@ -1,12 +1,16 @@
// @ts-nocheck
"use client";
import { FC, useEffect, useState } from "react";
import { Admin, Resource } from "react-admin";
import { useApolloClient } from "@apollo/client";
import polyglotI18nProvider from "ra-i18n-polyglot";
import { ThemeProvider, createTheme } from "@mui/material";
import { metamigoDataProvider } from "../lib/dataprovider";
import { metamigoDataProvider } from "../_lib/dataprovider";
import { theme } from "./layout/themes";
import { Layout } from "./layout";
import englishMessages from "../i18n/en";
import englishMessages from "../_i18n/en";
import users from "./users";
import accounts from "./accounts";
import whatsappBots from "./whatsapp/bots";
@ -20,7 +24,7 @@ import { AdminLogin, authProvider } from "./AdminLogin";
const i18nProvider = polyglotI18nProvider(
(_locale: any) => englishMessages,
"en"
"en",
);
const MetamigoAdmin: FC = () => {
@ -44,6 +48,7 @@ const MetamigoAdmin: FC = () => {
dataProvider={dataProvider}
layout={Layout}
i18nProvider={i18nProvider}
// @ts-ignore
loginPage={AdminLogin}
// @ts-ignore
authProvider={authProvider}

View file

@ -0,0 +1,8 @@
"use client";
import { FC, PropsWithChildren } from "react";
import { SessionProvider } from "next-auth/react";
export const MultiProvider: FC<PropsWithChildren> = ({ children }) => (
<SessionProvider>{children}</SessionProvider>
);

View file

@ -1,3 +1,5 @@
"use client";
import { FC } from "react";
import { makeStyles } from "@mui/styles";
import {
@ -25,7 +27,7 @@ type AccountEditToolbarProps = {
record?: any;
};
const AccountEditToolbar: FC<AccountEditToolbarProps> = (props: any) => {
const AccountEditToolbar: FC<AccountEditToolbarProps> = (props) => {
const { data: session } = useSession();
const classes = useStyles(props);
return (
@ -41,7 +43,7 @@ const AccountTitle = ({ record }: { record?: any }) => {
return <span>Account {title}</span>;
};
export const AccountEdit = (props: EditProps) => (
export const AccountEdit: FC<EditProps> = (props) => (
<Edit title={<AccountTitle />} {...props}>
<SimpleForm toolbar={<AccountEditToolbar />}>
<TextInput disabled source="id" />
@ -56,4 +58,5 @@ export const AccountEdit = (props: EditProps) => (
</SimpleForm>
</Edit>
);
export default AccountEdit;

View file

@ -1,3 +1,5 @@
"use client";
import { FC } from "react";
import {
List,
@ -14,7 +16,7 @@ type DeleteNotSelfButtonProps = {
record?: any;
};
const DeleteNotSelfButton: FC<DeleteNotSelfButtonProps> = (props: any) => {
const DeleteNotSelfButton: FC<DeleteNotSelfButtonProps> = (props) => {
const { data: session } = useSession();
return (
// @ts-ignore
@ -25,7 +27,7 @@ const DeleteNotSelfButton: FC<DeleteNotSelfButtonProps> = (props: any) => {
);
};
export const AccountList = (props: ListProps) => (
export const AccountList: FC<ListProps> = (props) => (
<List {...props} exporter={false}>
<Datagrid rowClick="edit">
<ReferenceField source="userId" reference="users">

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable import/no-named-as-default */
/* eslint-disable import/no-anonymous-default-export */
import AccountIcon from "@mui/icons-material/AccountTree";

View file

@ -1,3 +1,5 @@
"use client";
import { forwardRef } from "react";
import { AppBar, UserMenu, MenuItemLink, useTranslate } from "react-admin";
import Typography from "@mui/material/Typography";
@ -40,14 +42,19 @@ const CustomUserMenu = (props: any) => (
const CustomAppBar = (props: any) => {
const classes = useStyles();
return (
<AppBar {...props} elevation={1} userMenu={<CustomUserMenu />}>
<AppBar
{...props}
elevation={1}
userMenu={<CustomUserMenu />}
position="sticky"
sx={{ mt: -1 }}
>
<Typography
variant="h6"
color="inherit"
className={classes.title}
id="react-admin-title"
/>
<span className={classes.spacer} />
</AppBar>
);
};

View file

@ -1,4 +1,5 @@
/* eslint-disable import/no-named-as-default */
"use client";
import { Layout as RaLayout, LayoutProps, Sidebar } from "react-admin";
import AppBar from "./AppBar";
import Menu from "./Menu";
@ -6,15 +7,13 @@ import { theme } from "./themes";
const CustomSidebar = (props: any) => <Sidebar {...props} size={200} />;
const Layout = (props: LayoutProps) => (
export const Layout = (props: LayoutProps) => (
<RaLayout
{...props}
appBar={AppBar}
menu={Menu}
menu={Menu as any}
sidebar={CustomSidebar}
// @ts-ignore
theme={theme}
/>
);
export default Layout;

View file

@ -1,3 +1,5 @@
"use client";
import { SVGProps } from "react";
const Logo = (props: SVGProps<SVGSVGElement>) => (

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable camelcase */
import { FC, useState } from "react";
// import { useSelector } from "react-redux";

View file

@ -1,3 +1,5 @@
"use client";
import { FC, PropsWithChildren, Fragment, ReactElement } from "react";
import ExpandMore from "@mui/icons-material/ExpandMore";
import List from "@mui/material/List";

View file

@ -1,3 +1,5 @@
"use client";
export { default as AppBar } from "./AppBar";
export { default as Layout } from "./Layout";
export { Layout } from "./Layout";
export { default as Menu } from "./Menu";

View file

@ -1,3 +1,6 @@
"use client";
import { FC } from "react";
import {
SimpleForm,
Create,
@ -6,9 +9,9 @@ import {
CreateProps,
} from "react-admin";
import { useSession } from "next-auth/react";
import { validateE164Number } from "../../../lib/phone-numbers";
import { validateE164Number } from "../../../_lib/phone-numbers";
const SignalBotCreate = (props: CreateProps) => {
const SignalBotCreate: FC<CreateProps> = (props) => {
const { data: session } = useSession();
return (

View file

@ -1,6 +1,9 @@
"use client";
import { FC } from "react";
import { SimpleForm, Edit, TextInput, required, EditProps } from "react-admin";
const SignalBotEdit = (props: EditProps) => (
const SignalBotEdit: FC<EditProps> = (props) => (
<Edit {...props} title="Edit Bot">
<SimpleForm>
<TextInput disabled source="phoneNumber" validate={[required()]} />

View file

@ -1,3 +1,6 @@
"use client";
import { FC } from "react";
import {
List,
Datagrid,
@ -7,7 +10,7 @@ import {
ListProps,
} from "react-admin";
const SignalBotList = (props: ListProps) => (
const SignalBotList: FC<ListProps> = (props) => (
<List {...props} exporter={false}>
<Datagrid rowClick="show">
<TextField source="phoneNumber" />

View file

@ -1,4 +1,6 @@
import React, { useState } from "react";
"use client";
import { FC, useEffect, useState } from "react";
import {
Show,
SimpleShowLayout,
@ -28,7 +30,7 @@ import { SixDigitInput } from "../../DigitInput";
import {
sanitizeE164Number,
isValidE164Number,
} from "../../../lib/phone-numbers";
} from "../../../_lib/phone-numbers";
const Sidebar = ({ record }: any) => {
const [phoneNumber, setPhoneNumber] = useState("");
@ -173,7 +175,7 @@ const VerificationCodeRequest = ({
onSuccess,
onError,
}: any) => {
React.useEffect(() => {
useEffect(() => {
(async () => {
await handleRequestCode({
verifyMode,
@ -207,8 +209,8 @@ const VerificationCaptcha = ({
onError,
handleClose,
}: any) => {
const [code, setCode] = React.useState(undefined);
const [isSubmitting, setSubmitting] = React.useState(false);
const [code, setCode] = useState(undefined);
const [isSubmitting, setSubmitting] = useState(false);
const handleSubmitVerification = async () => {
setSubmitting(true);
@ -269,10 +271,10 @@ const VerificationCodeInput = ({
handleRestartVerification,
confirmVerification,
}: any) => {
const [code, setValue] = React.useState("");
const [isSubmitting, setSubmitting] = React.useState(false);
const [isValid, setValid] = React.useState(false);
const [submissionError, setSubmissionError] = React.useState(undefined);
const [code, setValue] = useState("");
const [isSubmitting, setSubmitting] = useState(false);
const [isValid, setValid] = useState(false);
const [submissionError, setSubmissionError] = useState(undefined);
const translate = useTranslate();
const validator = (v: any) => v.trim().length === 6;
@ -359,7 +361,7 @@ const VerificationCodeInput = ({
};
const VerificationCodeDialog = (props: any) => {
const [stage, setStage] = React.useState("request");
const [stage, setStage] = useState("request");
const onRequestSuccess = () => setStage("verify");
const onRestartVerification = () => setStage("request");
const handleClose = () => {
@ -410,8 +412,8 @@ const VerificationCodeDialog = (props: any) => {
};
const SignalBotShowActions = ({ data }: any) => {
const [open, setOpen] = React.useState(false);
const [verifyMode, setVerifyMode] = React.useState("");
const [open, setOpen] = useState(false);
const [verifyMode, setVerifyMode] = useState("");
const refresh = useRefresh();
const handleOpenSMS = () => {
@ -456,7 +458,7 @@ const SignalBotShowActions = ({ data }: any) => {
);
};
const SignalBotShow = (props: ShowProps) => (
const SignalBotShow: FC<ShowProps> = (props) => (
<Show
actions={<SignalBotShowActions />}
{...props}

View file

@ -1,3 +1,5 @@
"use client";
import SignalBotIcon from "@mui/icons-material/ChatOutlined";
import SignalBotList from "./SignalBotList";
import SignalBotEdit from "./SignalBotEdit";

View file

@ -0,0 +1,34 @@
"use client";
import { FC } from "react";
/* eslint-disable react/display-name */
import {
SelectInput,
required,
ReferenceInput,
ReferenceField,
TextField,
} from "react-admin";
export const SignalBotSelectInput =
(source: string): FC =>
() =>
(
<ReferenceInput
label="Signal Bot"
source={source}
reference="signalBots"
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const SignalBotField =
(source: string): FC =>
() =>
(
<ReferenceField label="Signal Bot" reference="signalBots" source={source}>
<TextField source="phoneNumber" />
</ReferenceField>
);

View file

@ -1,3 +1,5 @@
"use client";
import { FC } from "react";
import {
SimpleForm,

View file

@ -1,3 +1,5 @@
"use client";
import { makeStyles } from "@mui/styles";
import {
SimpleForm,

View file

@ -1,3 +1,6 @@
"use client";
import { FC } from "react";
import {
List,
Datagrid,
@ -8,7 +11,7 @@ import {
BooleanField,
} from "react-admin";
const UserList = () => (
const UserList: FC = () => (
<List exporter={false}>
<Datagrid rowClick="edit">
<EmailField source="email" />

View file

@ -1,3 +1,5 @@
"use client";
import UserIcon from "@mui/icons-material/People";
import UserList from "./UserList";
import UserEdit from "./UserEdit";

View file

@ -1,3 +1,5 @@
"use client";
import { SelectInput, useRecordContext } from "react-admin";
export const UserRoleInput = (props: any) => {

View file

@ -1,3 +1,5 @@
"use client";
import { List, Datagrid, DateField, TextField, ListProps } from "react-admin";
const ProviderList = (props: ListProps) => (

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable import/no-anonymous-default-export */
import ProviderIcon from "@mui/icons-material/Business";
import ProviderList from "./ProviderList";

View file

@ -1,3 +1,5 @@
"use client";
import { SelectInput } from "react-admin";
export const ProviderKindInput = (props: any) => (

View file

@ -1,3 +1,5 @@
"use client";
import { useInput } from "react-admin";
import React, { useState } from "react";
import dynamic from "next/dynamic";

View file

@ -1,3 +1,5 @@
"use client";
import VoiceLineIcon from "@mui/icons-material/PhoneCallback";
import VoiceLineList from "./VoiceLineList";
import VoiceLineEdit from "./VoiceLineEdit";

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable react/display-name */
import React, { useState, useEffect } from "react";
import PlayIcon from "@mui/icons-material/PlayCircleFilled";
@ -12,7 +14,7 @@ import {
TextField,
} from "react-admin";
import { IconButton, CircularProgress } from "@mui/material";
import absoluteUrl from "../../../lib/absolute-url";
import absoluteUrl from "../../../_lib/absolute-url";
import TwilioLanguages from "./twilio-languages";
type TTSProvider = (voice: any, language: any, prompt: any) => Promise<void>;

View file

@ -1,3 +1,5 @@
"use client";
import { List, Datagrid, DateField, TextField, ListProps } from "react-admin";
import { BackendIdField } from "./shared";

View file

@ -1,3 +1,5 @@
"use client";
import WebhookIcon from "@mui/icons-material/Send";
import WebhookList from "./WebhookList";
import WebhookEdit from "./WebhookEdit";

View file

@ -1,3 +1,5 @@
"use client";
import { SelectInput, required } from "react-admin";
import {

View file

@ -1,3 +1,5 @@
"use client";
import { List, Datagrid, TextField } from "react-admin";
const WhatsappAttachmentList = (props: any) => (

View file

@ -1,3 +1,5 @@
"use client";
import { Show, ShowProps, SimpleShowLayout, TextField } from "react-admin";
const WhatsappAttachmentShow = (props: ShowProps) => (

View file

@ -1,3 +1,5 @@
"use client";
import WhatsappAttachmentIcon from "@mui/icons-material/AttachFile";
import WhatsappAttachmentList from "./WhatsappAttachmentList";
import WhatsappAttachmentShow from "./WhatsappAttachmentShow";

View file

@ -1,9 +1,18 @@
// import dynamic from "next/dynamic";
import { SimpleForm, Create, TextInput, required } from "react-admin";
import { useSession } from "next-auth/react";
import { validateE164Number } from "../../../lib/phone-numbers";
"use client";
const WhatsappBotCreate = (props: any) => {
// import dynamic from "next/dynamic";
import { FC } from "react";
import {
SimpleForm,
Create,
TextInput,
required,
CreateProps,
} from "react-admin";
import { useSession } from "next-auth/react";
import { validateE164Number } from "../../../_lib/phone-numbers";
const WhatsappBotCreate: FC<CreateProps> = (props) => {
// const MuiPhoneNumber = dynamic(() => import("material-ui-phone-number"), {
// ssr: false,
// });

View file

@ -1,3 +1,5 @@
"use client";
import { SimpleForm, Edit, TextInput, required, EditProps } from "react-admin";
const WhatsappBotEdit = (props: EditProps) => (

View file

@ -1,3 +1,5 @@
"use client";
import React, { useEffect, useState } from "react";
import {
Card,

View file

@ -1,3 +1,5 @@
"use client";
import WhatsappBotIcon from "@mui/icons-material/WhatsApp";
import WhatsappBotList from "./WhatsappBotList";
import WhatsappBotEdit from "./WhatsappBotEdit";

View file

@ -1,3 +1,5 @@
"use client";
/* eslint-disable react/display-name */
import {
SelectInput,

View file

@ -1,3 +1,5 @@
"use client";
import WhatsappMessageIcon from "@mui/icons-material/Message";
import WhatsappMessageList from "./WhatsappMessageList";
import WhatsappMessageShow from "./WhatsappMessageShow";

View file

@ -0,0 +1,16 @@
"use client";
import { FC } from "react";
import { ApolloProvider } from "@apollo/client";
import { apolloClient } from "app/_lib/apollo-client";
import dynamic from "next/dynamic";
const MetamigoAdmin = dynamic(() => import("app/_components/MetamigoAdmin"), {
ssr: false,
});
export const Admin:FC = () => (
<ApolloProvider client={apolloClient}>
<MetamigoAdmin />
</ApolloProvider>
);

View file

@ -0,0 +1,5 @@
import { Admin } from "./_components/Admin";
export default function Home() {
return <Admin />
}

View file

@ -1,14 +1,14 @@
import { NextApiRequest, NextApiResponse } from "next";
import { NextRequest } from "next/server";
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import GitHub from "next-auth/providers/github";
import GitLab from "next-auth/providers/gitlab";
import Cognito from "next-auth/providers/cognito";
import { loadConfig, IAppConfig } from "@digiresilience/metamigo-config";
import { MetamigoAdapter } from "../../../lib/nextauth-adapter";
import { CloudflareAccessProvider } from "../../../lib/cloudflare";
import { MetamigoAdapter } from "app/_lib/nextauth-adapter";
import { CloudflareAccessProvider } from "app/_lib/cloudflare";
const nextAuthOptions = (config: IAppConfig, req: NextApiRequest) => {
const nextAuthOptions = (config: IAppConfig, req: NextRequest) => {
const { nextAuth, cfaccess } = config;
const adapter = MetamigoAdapter(config);
const providers = [];
@ -16,7 +16,7 @@ const nextAuthOptions = (config: IAppConfig, req: NextApiRequest) => {
const { audience, domain } = cfaccess;
const cloudflareAccessEnabled = audience && domain;
if (cloudflareAccessEnabled)
providers.push(CloudflareAccessProvider(audience, domain, adapter, req));
providers.push(CloudflareAccessProvider(audience, domain, adapter, req as any));
else {
if (nextAuth.google?.id)
providers.push(
@ -78,11 +78,11 @@ const nextAuthOptions = (config: IAppConfig, req: NextApiRequest) => {
};
};
const nextAuth = async (
req: NextApiRequest,
res: NextApiResponse
): Promise<void> =>
// @ts-expect-error: Type mismatch
NextAuth(req, res, nextAuthOptions(await loadConfig(), req));
const handler = async (req: NextRequest, context: any) => {
const config = await loadConfig();
const authOptions = nextAuthOptions(config, req);
// @ts-expect-error: non-existent property
return NextAuth(req, context, authOptions);
};
export default nextAuth;
export { handler as GET, handler as POST };

View file

@ -1,6 +1,6 @@
import { createProxyMiddleware } from "http-proxy-middleware";
export default createProxyMiddleware({
export const POST = createProxyMiddleware({
target:
process.env.NODE_ENV === "production"
? "http://metamigo-api:3001"
@ -28,9 +28,3 @@ export default createProxyMiddleware({
}
},
});
export const config = {
api: {
bodyParser: false,
},
};

View file

@ -1,6 +1,6 @@
import { createProxyMiddleware } from "http-proxy-middleware";
export default createProxyMiddleware({
const handler = createProxyMiddleware({
target:
process.env.NODE_ENV === "production"
? "http://metamigo-api:3001"
@ -30,8 +30,4 @@ export default createProxyMiddleware({
},
});
export const config = {
api: {
bodyParser: false,
},
};
export { handler as GET, handler as POST, handler as PUT, handler as DELETE};

View file

@ -0,0 +1,20 @@
import { ReactNode } from "react";
import "app/_styles/globals.css";
import { MultiProvider } from "./_components/MultiProvider";
type LayoutProps = {
children: ReactNode;
}
export default function Layout({ children }: LayoutProps) {
return (
<html lang="en">
<body>
<MultiProvider>
{children}
</MultiProvider>
</body>
</html>
);
}

View file

@ -1,8 +1,10 @@
"use client";
import { FC } from "react";
import { Button } from "@mui/material";
import { signIn, signOut, useSession } from "next-auth/react";
const MyComponent: FC = () => {
export const Login: FC = () => {
const { data: session } = useSession();
return (
@ -26,5 +28,3 @@ const MyComponent: FC = () => {
</>
);
};
export default MyComponent;

View file

@ -0,0 +1,5 @@
import { Login } from "./_components/Login";
export default function Page() {
return <Login />;
}

View file

@ -0,0 +1,3 @@
export default function Page() {
return null;
}

View file

@ -1,27 +0,0 @@
/* eslint-disable react/display-name */
import {
SelectInput,
required,
ReferenceInput,
ReferenceField,
TextField,
} from "react-admin";
export const SignalBotSelectInput = (source: string) => () =>
(
<ReferenceInput
label="Signal Bot"
source={source}
reference="signalBots"
validate={[required()]}
>
<SelectInput optionText="phoneNumber" />
</ReferenceInput>
);
export const SignalBotField = (source: string) => () =>
(
<ReferenceField label="Signal Bot" reference="signalBots" source={source}>
<TextField source="phoneNumber" />
</ReferenceField>
);

View file

@ -3,32 +3,32 @@
"version": "0.2.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.7.15",
"@apollo/client": "^3.7.17",
"@digiresilience/metamigo-config": "*",
"@hapi/boom": "^10.0.1",
"@hapi/wreck": "^18.0.1",
"@mui/icons-material": "^5",
"@mui/material": "^5",
"@mui/styles": "^5",
"@twilio/voice-sdk": "^2.6.0",
"@twilio/voice-sdk": "^2.6.1",
"http-proxy-middleware": "^2.0.6",
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.1",
"jwks-rsa": "^3.0.1",
"next": "13.4.6",
"next": "13.4.10",
"next-auth": "4.22.1",
"ra-data-graphql": "^4.11.3",
"ra-i18n-polyglot": "^4.11.3",
"ra-input-rich-text": "^4.11.3",
"ra-language-english": "^4.11.3",
"ra-data-graphql": "^4.12.1",
"ra-i18n-polyglot": "^4.12.1",
"ra-input-rich-text": "^4.12.1",
"ra-language-english": "^4.12.1",
"ra-postgraphile": "^6.1.1",
"react": "18.2.0",
"react-admin": "^4.11.3",
"react-admin": "^4.12.1",
"react-digit-input": "^2.1.0",
"react-dom": "18.2.0",
"react-qr-code": "^2.0.11",
"react-redux": "^8.1.1",
"react-timer-hook": "^3.0.6",
"swr": "^2.1.5",
"swr": "^2.2.0",
"twilio-client": "^1.15.0"
},
"scripts": {
@ -41,15 +41,15 @@
"fmt": "prettier --ignore-path .eslintignore \"**/*.{js,jsx,ts,tsx,graphql,md}\" --write"
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.4.6",
"@next/eslint-plugin-next": "^13.4.10",
"@types/hapi__wreck": "17.0.1",
"@types/react": "18.2.13",
"@types/react": "18.2.15",
"@types/react-mic": "12.4.3",
"babel-preset-link": "*",
"eslint-config-link": "*",
"jest-config-link": "*",
"tsconfig-link": "*",
"typescript": "5.1.3"
"typescript": "5.1.6"
},
"overrides": {
"@mui/styles": {

View file

@ -1,13 +0,0 @@
import "../styles/globals.css";
import { AppProps } from "next/app";
import { SessionProvider } from "next-auth/react";
function MetamigoStarter({ Component, pageProps }: AppProps) {
return (
<SessionProvider session={(pageProps as any).session}>
<Component {...pageProps} />
</SessionProvider>
);
}
export default MetamigoStarter;

View file

@ -1,15 +0,0 @@
import { ApolloProvider } from "@apollo/client";
import { apolloClient } from "../lib/apollo-client";
import dynamic from "next/dynamic";
const MetamigoAdmin = dynamic(() => import("../components/MetamigoAdmin"), {
ssr: false,
});
export default function Home() {
return (
<ApolloProvider client={apolloClient}>
<MetamigoAdmin />
</ApolloProvider>
);
}

View file

@ -1,29 +0,0 @@
import { NextPage } from "next";
import { Typography, Box, Button, Grid, Link } from "@mui/material";
import { FC, useEffect, PropsWithChildren } from "react";
import { useRouter } from "next/router";
export const RedirectToAdmin: FC<PropsWithChildren> = ({ children }) => {
const router = useRouter();
useEffect(() => {
router.push("/admin");
});
return <>{children}</>;
};
const Home: NextPage = () => (
<Box>
<Typography variant="h3">Metamigo</Typography>
<Grid container justifyContent="space-around" style={{ padding: 60 }}>
<Grid item>
<Link href="/admin">
<Button variant="contained">Admin</Button>
<RedirectToAdmin />
</Link>
</Grid>
</Grid>
</Box>
);
export default Home;

View file

@ -2,7 +2,11 @@
"extends": "tsconfig-link",
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
@ -17,9 +21,24 @@
"strict": true,
"baseUrl": ".",
"paths": {
"@/*": ["./*", "../../node_modules/*"]
}
"@/*": [
"./*",
"../../node_modules/*"
]
},
"plugins": [
{
"name": "next"
}
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}