diff --git a/apps/leafcutter/components/AboutBox.tsx b/apps/leafcutter/app/_components/AboutBox.tsx similarity index 97% rename from apps/leafcutter/components/AboutBox.tsx rename to apps/leafcutter/app/_components/AboutBox.tsx index c8d06e9..b90f1a5 100644 --- a/apps/leafcutter/components/AboutBox.tsx +++ b/apps/leafcutter/app/_components/AboutBox.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, PropsWithChildren } from "react"; import { Box } from "@mui/material"; import { useAppContext } from "./AppProvider"; diff --git a/apps/leafcutter/components/AboutFeature.tsx b/apps/leafcutter/app/_components/AboutFeature.tsx similarity index 99% rename from apps/leafcutter/components/AboutFeature.tsx rename to apps/leafcutter/app/_components/AboutFeature.tsx index b8ff04c..ca46fc9 100644 --- a/apps/leafcutter/components/AboutFeature.tsx +++ b/apps/leafcutter/app/_components/AboutFeature.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC } from "react"; import Image from "next/legacy/image"; import { Grid, Box, GridSize } from "@mui/material"; diff --git a/apps/leafcutter/components/AccountButton.tsx b/apps/leafcutter/app/_components/AccountButton.tsx similarity index 98% rename from apps/leafcutter/components/AccountButton.tsx rename to apps/leafcutter/app/_components/AccountButton.tsx index 82a324b..45a3f4e 100644 --- a/apps/leafcutter/components/AccountButton.tsx +++ b/apps/leafcutter/app/_components/AccountButton.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC } from "react"; import Image from "next/legacy/image"; import { signOut } from "next-auth/react"; diff --git a/apps/leafcutter/components/AppProvider.tsx b/apps/leafcutter/app/_components/AppProvider.tsx similarity index 99% rename from apps/leafcutter/components/AppProvider.tsx rename to apps/leafcutter/app/_components/AppProvider.tsx index f829271..cc4c879 100644 --- a/apps/leafcutter/components/AppProvider.tsx +++ b/apps/leafcutter/app/_components/AppProvider.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, createContext, diff --git a/apps/leafcutter/components/Button.tsx b/apps/leafcutter/app/_components/Button.tsx similarity index 98% rename from apps/leafcutter/components/Button.tsx rename to apps/leafcutter/app/_components/Button.tsx index 923705c..461bf46 100644 --- a/apps/leafcutter/components/Button.tsx +++ b/apps/leafcutter/app/_components/Button.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC } from "react"; import Link from "next/link"; import { Button as MUIButton } from "@mui/material"; diff --git a/apps/leafcutter/components/Footer.tsx b/apps/leafcutter/app/_components/Footer.tsx similarity index 99% rename from apps/leafcutter/components/Footer.tsx rename to apps/leafcutter/app/_components/Footer.tsx index 49ec23b..b81d54d 100644 --- a/apps/leafcutter/components/Footer.tsx +++ b/apps/leafcutter/app/_components/Footer.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC } from "react"; import { Container, Grid, Box, Button } from "@mui/material"; import { useTranslate } from "react-polyglot"; diff --git a/apps/leafcutter/components/GettingStartedDialog.tsx b/apps/leafcutter/app/_components/GettingStartedDialog.tsx similarity index 99% rename from apps/leafcutter/components/GettingStartedDialog.tsx rename to apps/leafcutter/app/_components/GettingStartedDialog.tsx index 1e5f94c..c50e4ca 100644 --- a/apps/leafcutter/components/GettingStartedDialog.tsx +++ b/apps/leafcutter/app/_components/GettingStartedDialog.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useState } from "react"; import { Dialog, Box, Grid, Checkbox, IconButton } from "@mui/material"; import { Close as CloseIcon } from "@mui/icons-material"; diff --git a/apps/leafcutter/components/HelpButton.tsx b/apps/leafcutter/app/_components/HelpButton.tsx similarity index 98% rename from apps/leafcutter/components/HelpButton.tsx rename to apps/leafcutter/app/_components/HelpButton.tsx index a67b1a2..f4e2bb0 100644 --- a/apps/leafcutter/components/HelpButton.tsx +++ b/apps/leafcutter/app/_components/HelpButton.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useState } from "react"; import { useRouter } from "next/router"; import { Button } from "@mui/material"; diff --git a/apps/leafcutter/pages/index.tsx b/apps/leafcutter/app/_components/Home.tsx similarity index 68% rename from apps/leafcutter/pages/index.tsx rename to apps/leafcutter/app/_components/Home.tsx index 9432e08..58c9776 100644 --- a/apps/leafcutter/pages/index.tsx +++ b/apps/leafcutter/app/_components/Home.tsx @@ -1,30 +1,23 @@ -import { useEffect } from "react"; -import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next"; +"use client"; + +import { useEffect, FC } from "react"; import { useRouter } from "next/router"; -import { getSession } from "next-auth/react"; -import Head from "next/head"; import Link from "next/link"; import ReactMarkdown from "react-markdown"; import { Grid, Button } from "@mui/material"; import { useTranslate } from "react-polyglot"; import { useCookies } from "react-cookie"; -import { Layout } from "components/Layout"; -import { getUserVisualizations } from "lib/opensearch"; -import { Welcome } from "components/Welcome"; -import { WelcomeDialog } from "components/WelcomeDialog"; -import { VisualizationCard } from "components/VisualizationCard"; -import { useAppContext } from "components/AppProvider"; -import { getEmbedded } from "lib/utils"; +import { Welcome } from "@/app/_components/Welcome"; +import { WelcomeDialog } from "@/app/_components/WelcomeDialog"; +import { VisualizationCard } from "@/app/_components/VisualizationCard"; +import { useAppContext } from "@/app/_components/AppProvider"; -type MyVisualizationsProps = { +type HomeProps = { visualizations: any; embedded: boolean; }; -const MyVisualizations: NextPage = ({ - visualizations, - embedded, -}) => { +export const Home: FC = ({ visualizations, embedded }) => { const router = useRouter(); const cookieName = "homeIntroComplete"; const [cookies, setCookie] = useCookies([cookieName]); @@ -43,10 +36,7 @@ const MyVisualizations: NextPage = ({ }, [homeIntroComplete, router, setCookie]); return ( - - - Digital Threat Dashboard – Leafcutter - + <> = ({ ))} - + ); }; - -export default MyVisualizations; - -export const getServerSideProps: GetServerSideProps = async ( - context: GetServerSidePropsContext -) => { - const session = (await getSession(context)) ?? null; - const visualizations = await getUserVisualizations( - session?.user?.email ?? "none", - 20 - ); - return { props: { visualizations, embedded: getEmbedded(context) } }; -}; diff --git a/apps/leafcutter/components/Layout.tsx b/apps/leafcutter/app/_components/InternalLayout.tsx similarity index 96% rename from apps/leafcutter/components/Layout.tsx rename to apps/leafcutter/app/_components/InternalLayout.tsx index 29a63fc..33166f2 100644 --- a/apps/leafcutter/components/Layout.tsx +++ b/apps/leafcutter/app/_components/InternalLayout.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, PropsWithChildren } from "react"; import getConfig from "next/config"; import { Grid, Container } from "@mui/material"; @@ -13,7 +15,7 @@ type LayoutProps = PropsWithChildren<{ embedded?: boolean; }>; -export const Layout: FC = ({ +export const InternalLayout: FC = ({ embedded = false, children, }: any) => { diff --git a/apps/leafcutter/components/LanguageSelect.tsx b/apps/leafcutter/app/_components/LanguageSelect.tsx similarity index 99% rename from apps/leafcutter/components/LanguageSelect.tsx rename to apps/leafcutter/app/_components/LanguageSelect.tsx index e8b4fbf..c965b0c 100644 --- a/apps/leafcutter/components/LanguageSelect.tsx +++ b/apps/leafcutter/app/_components/LanguageSelect.tsx @@ -1,3 +1,5 @@ +"use client"; + import { useRouter } from "next/router"; import { IconButton, Menu, MenuItem, Box } from "@mui/material"; import { KeyboardArrowDown as KeyboardArrowDownIcon } from "@mui/icons-material"; diff --git a/apps/leafcutter/components/LiveDataViewer.tsx b/apps/leafcutter/app/_components/LiveDataViewer.tsx similarity index 97% rename from apps/leafcutter/components/LiveDataViewer.tsx rename to apps/leafcutter/app/_components/LiveDataViewer.tsx index 9ff9436..c69f9cd 100644 --- a/apps/leafcutter/components/LiveDataViewer.tsx +++ b/apps/leafcutter/app/_components/LiveDataViewer.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useEffect, useState } from "react"; import { useAppContext } from "./AppProvider"; import { RawDataViewer } from "./RawDataViewer"; diff --git a/apps/leafcutter/components/MetricSelectCard.tsx b/apps/leafcutter/app/_components/MetricSelectCard.tsx similarity index 99% rename from apps/leafcutter/components/MetricSelectCard.tsx rename to apps/leafcutter/app/_components/MetricSelectCard.tsx index 60a08f5..f40bb92 100644 --- a/apps/leafcutter/components/MetricSelectCard.tsx +++ b/apps/leafcutter/app/_components/MetricSelectCard.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useState } from "react"; import { Card, Grid } from "@mui/material"; import { diff --git a/apps/leafcutter/app/_components/MultiProvider.tsx b/apps/leafcutter/app/_components/MultiProvider.tsx new file mode 100644 index 0000000..4785653 --- /dev/null +++ b/apps/leafcutter/app/_components/MultiProvider.tsx @@ -0,0 +1,47 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import { FC, PropsWithChildren } from "react"; +import { SessionProvider } from "next-auth/react"; +import { CssBaseline } from "@mui/material"; +import { CookiesProvider } from "react-cookie"; +import { I18n } from "react-polyglot"; +import { AdapterDateFns } from "@mui/x-date-pickers-pro/AdapterDateFns"; +("use client"); + +import { LocalizationProvider } from "@mui/x-date-pickers-pro"; +import { AppProvider } from "@/app/_components/AppProvider"; +import { NextAppDirEmotionCacheProvider } from "tss-react/next/appDir"; +import en from "locales/en.json"; +import fr from "locales/fr.json"; +import "@fontsource/poppins/400.css"; +import "@fontsource/poppins/700.css"; +import "@fontsource/roboto/400.css"; +import "@fontsource/roboto/700.css"; +import "@fontsource/playfair-display/900.css"; +import "styles/global.css"; +import { LicenseInfo } from "@mui/x-data-grid-pro"; + +LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY ?? ""); + +const messages: any = { en, fr }; + +export const MultiProvider: FC = ({ children }: any) => { + // const { locale = "en" } = useRouter(); + const locale = "en"; + + return ( + + + + + + + + {children} + + + + + + + ); +}; diff --git a/apps/leafcutter/components/OpenSearchWrapper.tsx b/apps/leafcutter/app/_components/OpenSearchWrapper.tsx similarity index 98% rename from apps/leafcutter/components/OpenSearchWrapper.tsx rename to apps/leafcutter/app/_components/OpenSearchWrapper.tsx index 4f74208..2ec8f79 100644 --- a/apps/leafcutter/components/OpenSearchWrapper.tsx +++ b/apps/leafcutter/app/_components/OpenSearchWrapper.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC } from "react"; import Iframe from "react-iframe"; import { Box } from "@mui/material"; diff --git a/apps/leafcutter/components/PageHeader.tsx b/apps/leafcutter/app/_components/PageHeader.tsx similarity index 98% rename from apps/leafcutter/components/PageHeader.tsx rename to apps/leafcutter/app/_components/PageHeader.tsx index 46c31d2..65b60c4 100644 --- a/apps/leafcutter/components/PageHeader.tsx +++ b/apps/leafcutter/app/_components/PageHeader.tsx @@ -1,3 +1,5 @@ +"use client"; + /* eslint-disable react/require-default-props */ import { FC, PropsWithChildren } from "react"; import { Box } from "@mui/material"; diff --git a/apps/leafcutter/components/QueryBuilder.tsx b/apps/leafcutter/app/_components/QueryBuilder.tsx similarity index 98% rename from apps/leafcutter/components/QueryBuilder.tsx rename to apps/leafcutter/app/_components/QueryBuilder.tsx index bbf8846..8861da9 100644 --- a/apps/leafcutter/components/QueryBuilder.tsx +++ b/apps/leafcutter/app/_components/QueryBuilder.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useState } from "react"; import { Box, @@ -15,14 +17,14 @@ import { Group as GroupIcon, } from "@mui/icons-material"; import { useTranslate } from "react-polyglot"; -import taxonomy from "config/taxonomy.json"; +import taxonomy from "app/_config/taxonomy.json"; import { QueryBuilderSection } from "./QueryBuilderSection"; import { QueryListSelector } from "./QueryListSelector"; import { QueryDateRangeSelector } from "./QueryDateRangeSelector"; import { useAppContext } from "./AppProvider"; import { Tooltip } from "./Tooltip"; -interface QueryBuilderProps { } +interface QueryBuilderProps {} export const QueryBuilder: FC = () => { const t = useTranslate(); diff --git a/apps/leafcutter/components/QueryBuilderSection.tsx b/apps/leafcutter/app/_components/QueryBuilderSection.tsx similarity index 99% rename from apps/leafcutter/components/QueryBuilderSection.tsx rename to apps/leafcutter/app/_components/QueryBuilderSection.tsx index 99dad2e..b8ec4c7 100644 --- a/apps/leafcutter/components/QueryBuilderSection.tsx +++ b/apps/leafcutter/app/_components/QueryBuilderSection.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, PropsWithChildren, useState } from "react"; import { Box, diff --git a/apps/leafcutter/components/QueryDateRangeSelector.tsx b/apps/leafcutter/app/_components/QueryDateRangeSelector.tsx similarity index 98% rename from apps/leafcutter/components/QueryDateRangeSelector.tsx rename to apps/leafcutter/app/_components/QueryDateRangeSelector.tsx index bc8c82e..ae4fce2 100644 --- a/apps/leafcutter/components/QueryDateRangeSelector.tsx +++ b/apps/leafcutter/app/_components/QueryDateRangeSelector.tsx @@ -1,3 +1,5 @@ +"use client"; + import { FC, useState, useEffect } from "react"; import { Box, Grid, TextField, Select, MenuItem } from "@mui/material"; import { DatePicker } from "@mui/x-date-pickers-pro"; @@ -90,7 +92,7 @@ export const QueryDateRangeSelector: FC = () => { endDate: { values: [date] }, }); }} - // @ts-ignore + // @ts-ignore renderInput={(params) => ( = ({ embedded }) => { } = useAppContext(); return ( - - - Digital Threat Dashboard – Leafcutter - + <> = ({ embedded }) => { - + ); }; diff --git a/apps/leafcutter/pages/api/auth/[...nextauth].ts b/apps/leafcutter/app/api/auth/[...nextauth]/route.ts similarity index 86% rename from apps/leafcutter/pages/api/auth/[...nextauth].ts rename to apps/leafcutter/app/api/auth/[...nextauth]/route.ts index 0705c42..145e34c 100644 --- a/apps/leafcutter/pages/api/auth/[...nextauth].ts +++ b/apps/leafcutter/app/api/auth/[...nextauth]/route.ts @@ -2,7 +2,7 @@ import NextAuth from "next-auth"; import Google from "next-auth/providers/google"; import Apple from "next-auth/providers/apple"; -export default NextAuth({ +const handler = NextAuth({ providers: [ Google({ clientId: process.env.GOOGLE_CLIENT_ID ?? "", @@ -15,3 +15,5 @@ export default NextAuth({ ], secret: process.env.NEXTAUTH_SECRET, }); + +export { handler as GET, handler as POST }; diff --git a/apps/leafcutter/pages/api/proxy/[[...path]].ts b/apps/leafcutter/app/api/proxy/[[...path]].ts similarity index 100% rename from apps/leafcutter/pages/api/proxy/[[...path]].ts rename to apps/leafcutter/app/api/proxy/[[...path]].ts diff --git a/apps/leafcutter/pages/api/searches/create.ts b/apps/leafcutter/app/api/searches/create.ts similarity index 83% rename from apps/leafcutter/pages/api/searches/create.ts rename to apps/leafcutter/app/api/searches/create.ts index 569c434..31c9e2c 100644 --- a/apps/leafcutter/pages/api/searches/create.ts +++ b/apps/leafcutter/app/api/searches/create.ts @@ -1,8 +1,8 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { getUserMetadata, saveUserMetadata } from "lib/opensearch"; +import { getUserMetadata, saveUserMetadata } from "@/app/_lib/opensearch"; -const handler = async (req: NextApiRequest, res: NextApiResponse) => { +export const POST = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ req, secret: process.env.NEXTAUTH_SECRET, @@ -27,7 +27,6 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { return res.json(updatedSavedSearches); }; -export default handler; diff --git a/apps/leafcutter/pages/api/searches/delete.ts b/apps/leafcutter/app/api/searches/delete.ts similarity index 91% rename from apps/leafcutter/pages/api/searches/delete.ts rename to apps/leafcutter/app/api/searches/delete.ts index 61108bd..83cfc1e 100644 --- a/apps/leafcutter/pages/api/searches/delete.ts +++ b/apps/leafcutter/app/api/searches/delete.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { getUserMetadata, saveUserMetadata } from "lib/opensearch"; +import { getUserMetadata, saveUserMetadata } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ diff --git a/apps/leafcutter/pages/api/searches/list.ts b/apps/leafcutter/app/api/searches/list.ts similarity index 91% rename from apps/leafcutter/pages/api/searches/list.ts rename to apps/leafcutter/app/api/searches/list.ts index 1e0fc77..eabb048 100644 --- a/apps/leafcutter/pages/api/searches/list.ts +++ b/apps/leafcutter/app/api/searches/list.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { getUserMetadata } from "lib/opensearch"; +import { getUserMetadata } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ diff --git a/apps/leafcutter/app/api/trends/recent.ts b/apps/leafcutter/app/api/trends/recent.ts new file mode 100644 index 0000000..94b3cc1 --- /dev/null +++ b/apps/leafcutter/app/api/trends/recent.ts @@ -0,0 +1,20 @@ +import { NextResponse } from "next/server"; +// import { getToken } from "next-auth/jwt"; +import { getTrends } from "@/app/_lib/opensearch"; + +export const GET = async () => { + /* + const session = await getToken({ + req, + secret: process.env.NEXTAUTH_SECRET, + }); + + if (!session) { + return res.redirect("/login"); + } +*/ + const results = await getTrends(5); + + NextResponse.json(results); +}; + diff --git a/apps/leafcutter/pages/api/upload/index.ts b/apps/leafcutter/app/api/upload/index.ts similarity index 93% rename from apps/leafcutter/pages/api/upload/index.ts rename to apps/leafcutter/app/api/upload/index.ts index 73afd1f..80bb338 100644 --- a/apps/leafcutter/pages/api/upload/index.ts +++ b/apps/leafcutter/app/api/upload/index.ts @@ -2,8 +2,8 @@ import { NextApiRequest, NextApiResponse } from "next"; import { Client } from "@opensearch-project/opensearch"; import { v4 as uuid } from "uuid"; -import taxonomy from "config/taxonomy.json"; -import unRegions from "config/unRegions.json"; +import taxonomy from "app/_config/taxonomy.json"; +import unRegions from "app/_config/unRegions.json"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const { headers: { authorization }, body: { tickets } } = req; diff --git a/apps/leafcutter/pages/api/visualizations/create.ts b/apps/leafcutter/app/api/visualizations/create.ts similarity index 92% rename from apps/leafcutter/pages/api/visualizations/create.ts rename to apps/leafcutter/app/api/visualizations/create.ts index 7759746..06eb2cf 100644 --- a/apps/leafcutter/pages/api/visualizations/create.ts +++ b/apps/leafcutter/app/api/visualizations/create.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { createUserVisualization } from "lib/opensearch"; +import { createUserVisualization } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ diff --git a/apps/leafcutter/pages/api/visualizations/delete.ts b/apps/leafcutter/app/api/visualizations/delete.ts similarity index 90% rename from apps/leafcutter/pages/api/visualizations/delete.ts rename to apps/leafcutter/app/api/visualizations/delete.ts index 96a755d..73aba5a 100644 --- a/apps/leafcutter/pages/api/visualizations/delete.ts +++ b/apps/leafcutter/app/api/visualizations/delete.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { deleteUserVisualization } from "lib/opensearch"; +import { deleteUserVisualization } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ diff --git a/apps/leafcutter/pages/api/visualizations/query.ts b/apps/leafcutter/app/api/visualizations/query.ts similarity index 86% rename from apps/leafcutter/pages/api/visualizations/query.ts rename to apps/leafcutter/app/api/visualizations/query.ts index c73102c..89ccca2 100644 --- a/apps/leafcutter/pages/api/visualizations/query.ts +++ b/apps/leafcutter/app/api/visualizations/query.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { performQuery } from "lib/opensearch"; +import { performQuery } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ @@ -16,7 +16,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const rawQuery = await JSON.parse(decodeURI(searchQuery as string)); const results = await performQuery(rawQuery, 1000); - return res.json(results) + return res.json(results); }; export default handler; diff --git a/apps/leafcutter/pages/api/visualizations/update.ts b/apps/leafcutter/app/api/visualizations/update.ts similarity index 91% rename from apps/leafcutter/pages/api/visualizations/update.ts rename to apps/leafcutter/app/api/visualizations/update.ts index b6d77d1..7b8e2e8 100644 --- a/apps/leafcutter/pages/api/visualizations/update.ts +++ b/apps/leafcutter/app/api/visualizations/update.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import { getToken } from "next-auth/jwt"; -import { updateUserVisualization } from "lib/opensearch"; +import { updateUserVisualization } from "@/app/_lib/opensearch"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { const session = await getToken({ diff --git a/apps/leafcutter/pages/create.tsx b/apps/leafcutter/app/create/page.tsx similarity index 82% rename from apps/leafcutter/pages/create.tsx rename to apps/leafcutter/app/create/page.tsx index 865bebf..dfe6baa 100644 --- a/apps/leafcutter/pages/create.tsx +++ b/apps/leafcutter/app/create/page.tsx @@ -1,16 +1,14 @@ import { FC, useEffect } from "react"; import { GetServerSideProps, GetServerSidePropsContext } from "next"; -import Head from "next/head"; import { useTranslate } from "react-polyglot"; import { useRouter } from "next/router"; import { Box, Grid } from "@mui/material"; import { useCookies } from "react-cookie"; -import { getTemplates } from "lib/opensearch"; -import { Layout } from "components/Layout"; -import { useAppContext } from "components/AppProvider"; -import { PageHeader } from "components/PageHeader"; -import { VisualizationBuilder } from "components/VisualizationBuilder"; -import { getEmbedded } from "lib/utils"; +import { getTemplates } from "@/app/_lib/opensearch"; +import { useAppContext } from "@/app/_components/AppProvider"; +import { PageHeader } from "@/app/_components/PageHeader"; +import { VisualizationBuilder } from "@/app/_components/VisualizationBuilder"; +import { getEmbedded } from "@/app/_lib/utils"; type CreateProps = { templates: any; @@ -36,11 +34,7 @@ const Create: FC = ({ templates, embedded }) => { }, [searchIntroComplete, router, setCookie]); return ( - - - Digital Threat Dashboard – Leafcutter - - + <> {/* @@ -67,7 +61,7 @@ const Create: FC = ({ templates, embedded }) => { - + ); }; diff --git a/apps/leafcutter/pages/faq.tsx b/apps/leafcutter/app/faq/page.tsx similarity index 87% rename from apps/leafcutter/pages/faq.tsx rename to apps/leafcutter/app/faq/page.tsx index 61d976d..e3bf51d 100644 --- a/apps/leafcutter/pages/faq.tsx +++ b/apps/leafcutter/app/faq/page.tsx @@ -1,13 +1,11 @@ -import Head from "next/head"; import { useTranslate } from "react-polyglot"; import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next"; import { Box, Grid } from "@mui/material"; -import { Layout } from "components/Layout"; -import { PageHeader } from "components/PageHeader"; -import { Question } from "components/Question"; -import { useAppContext } from "components/AppProvider"; +import { PageHeader } from "@/app/_components/PageHeader"; +import { Question } from "@/app/_components/Question"; +import { useAppContext } from "@/app/_components/AppProvider"; import FaqHeader from "images/faq-header.svg"; -import { getEmbedded } from "lib/utils"; +import { getEmbedded } from "@/app/_lib/utils"; type FAQProps = { embedded: boolean; @@ -70,10 +68,7 @@ const FAQ: NextPage = ({ embedded }) => { ]; return ( - - - Digital Threat Dashboard – Leafcutter - + <> = ({ embedded }) => { {questions.map((q: any, index: number) => ( ))} - + ); }; diff --git a/apps/leafcutter/app/layout.tsx b/apps/leafcutter/app/layout.tsx new file mode 100644 index 0000000..a6c3119 --- /dev/null +++ b/apps/leafcutter/app/layout.tsx @@ -0,0 +1,36 @@ +import { ReactNode } from "react"; +import { Metadata } from "next"; +import "./_styles/global.css"; +import "@fontsource/poppins/400.css"; +import "@fontsource/poppins/700.css"; +import "@fontsource/roboto/400.css"; +import "@fontsource/roboto/700.css"; +import "@fontsource/playfair-display/900.css"; +import "styles/global.css"; +// import getConfig from "next/config"; +// import { LicenseInfo } from "@mui/x-data-grid-pro"; +import { MultiProvider } from "app/_components/MultiProvider"; +import { InternalLayout } from "app/_components/InternalLayout"; + +export const metadata: Metadata = { + title: "Leafcutter", +}; + +type LayoutProps = { + children: ReactNode; +}; + +export default function Layout({ children }: LayoutProps) { + // const { publicRuntimeConfig } = getConfig(); + // LicenseInfo.setLicenseKey(publicRuntimeConfig.muiLicenseKey); + + return ( + + + + {children} + + + + ); +} diff --git a/apps/leafcutter/pages/login.tsx b/apps/leafcutter/app/login/page.tsx similarity index 96% rename from apps/leafcutter/pages/login.tsx rename to apps/leafcutter/app/login/page.tsx index 30b4dbd..18d8ee8 100644 --- a/apps/leafcutter/pages/login.tsx +++ b/apps/leafcutter/app/login/page.tsx @@ -5,10 +5,10 @@ import Image from "next/legacy/image"; import { Box, Grid, Container, IconButton } from "@mui/material"; import { Apple as AppleIcon, Google as GoogleIcon } from "@mui/icons-material"; import { useTranslate } from "react-polyglot"; -import { LanguageSelect } from "components/LanguageSelect"; +import { LanguageSelect } from "@/app/_components/LanguageSelect"; import LeafcutterLogoLarge from "images/leafcutter-logo-large.png"; import { signIn, getSession } from "next-auth/react"; -import { useAppContext } from "components/AppProvider"; +import { useAppContext } from "@/app/_components/AppProvider"; type LoginProps = { session: any; diff --git a/apps/leafcutter/app/page.tsx b/apps/leafcutter/app/page.tsx new file mode 100644 index 0000000..34c8b7f --- /dev/null +++ b/apps/leafcutter/app/page.tsx @@ -0,0 +1,16 @@ +import { getSession } from "next-auth/react"; +import { getUserVisualizations } from "@/app/_lib/opensearch"; +import { getEmbedded } from "@/app/_lib/utils"; +import { Home } from "@/app/_components/Home"; + +export default async function Page() { + const context = undefined; + const session = (await getSession(context)) ?? null; + const visualizations = await getUserVisualizations( + session?.user?.email ?? "none", + 20 + ); + const embedded = false; // getEmbedded(context); + + return ; +} diff --git a/apps/leafcutter/pages/preview/[...visualizationID].tsx b/apps/leafcutter/app/preview/[...visualizationID]/page.tsx similarity index 94% rename from apps/leafcutter/pages/preview/[...visualizationID].tsx rename to apps/leafcutter/app/preview/[...visualizationID]/page.tsx index 6bb7188..c26032d 100644 --- a/apps/leafcutter/pages/preview/[...visualizationID].tsx +++ b/apps/leafcutter/app/preview/[...visualizationID]/page.tsx @@ -1,8 +1,8 @@ import { FC } from "react"; /* eslint-disable no-underscore-dangle */ // import { Client } from "@opensearch-project/opensearch"; -import { RawDataViewer } from "components/RawDataViewer"; -import { VisualizationDetail } from "components/VisualizationDetail"; +import { RawDataViewer } from "@/app/_components/RawDataViewer"; +import { VisualizationDetail } from "@/app/_components/VisualizationDetail"; // import { createVisualization } from "lib/opensearch"; interface PreviewProps { diff --git a/apps/leafcutter/pages/setup.tsx b/apps/leafcutter/app/setup/page.tsx similarity index 94% rename from apps/leafcutter/pages/setup.tsx rename to apps/leafcutter/app/setup/page.tsx index 17c1ce0..decf509 100644 --- a/apps/leafcutter/pages/setup.tsx +++ b/apps/leafcutter/app/setup/page.tsx @@ -3,7 +3,7 @@ import { NextPage } from "next"; import { useRouter } from "next/router"; import { Grid, CircularProgress } from "@mui/material"; import Iframe from "react-iframe"; -import { useAppContext } from "components/AppProvider"; +import { useAppContext } from "@/app/_components/AppProvider"; const Setup: NextPage = () => { const { diff --git a/apps/leafcutter/pages/trends.tsx b/apps/leafcutter/app/trends/page.tsx similarity index 83% rename from apps/leafcutter/pages/trends.tsx rename to apps/leafcutter/app/trends/page.tsx index 3ee350d..ccc817b 100644 --- a/apps/leafcutter/pages/trends.tsx +++ b/apps/leafcutter/app/trends/page.tsx @@ -2,12 +2,11 @@ import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next"; import Head from "next/head"; import { Grid, Box } from "@mui/material"; import { useTranslate } from "react-polyglot"; -import { Layout } from "components/Layout"; -import { getTrends } from "lib/opensearch"; -import { PageHeader } from "components/PageHeader"; -import { VisualizationCard } from "components/VisualizationCard"; -import { useAppContext } from "components/AppProvider"; -import { getEmbedded } from "lib/utils"; +import { getTrends } from "@/app/_lib/opensearch"; +import { PageHeader } from "@/app/_components/PageHeader"; +import { VisualizationCard } from "@/app/_components/VisualizationCard"; +import { useAppContext } from "@/app/_components/AppProvider"; +import { getEmbedded } from "@/app/_lib/utils"; type TrendsProps = { visualizations: any; @@ -22,10 +21,7 @@ const Trends: NextPage = ({ visualizations, embedded }) => { } = useAppContext(); return ( - - - Digital Threat Dashboard – Leafcutter - + <> = ({ visualizations, embedded }) => { /> ))} - + ); }; diff --git a/apps/leafcutter/pages/visualizations/[...visualizationID].tsx b/apps/leafcutter/app/visualizations/[...visualizationID]/page.tsx similarity index 78% rename from apps/leafcutter/pages/visualizations/[...visualizationID].tsx rename to apps/leafcutter/app/visualizations/[...visualizationID]/page.tsx index 03bc988..3491f5d 100644 --- a/apps/leafcutter/pages/visualizations/[...visualizationID].tsx +++ b/apps/leafcutter/app/visualizations/[...visualizationID]/page.tsx @@ -1,10 +1,8 @@ /* eslint-disable no-underscore-dangle */ import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next"; import { Client } from "@opensearch-project/opensearch"; -import Head from "next/head"; -import { Layout } from "components/Layout"; -import { VisualizationDetail } from "components/VisualizationDetail"; -import { getEmbedded } from "lib/utils"; +import { VisualizationDetail } from "@/app/_components/VisualizationDetail"; +import { getEmbedded } from "@/app/_lib/utils"; type VisualizationProps = { visualization: any; @@ -14,14 +12,7 @@ type VisualizationProps = { const Visualization: NextPage = ({ visualization, embedded, -}) => ( - - - Digital Threat Dashboard – Leafcutter - - - -); +}) => ; export default Visualization; diff --git a/apps/leafcutter/package.json b/apps/leafcutter/package.json index 88189c1..b6cd803 100644 --- a/apps/leafcutter/package.json +++ b/apps/leafcutter/package.json @@ -23,13 +23,13 @@ "@mui/icons-material": "^5", "@mui/lab": "^5.0.0-alpha.134", "@mui/material": "^5", - "@mui/x-data-grid-pro": "^6.8.0", - "@mui/x-date-pickers-pro": "^6.8.0", + "@mui/x-data-grid-pro": "^6.9.0", + "@mui/x-date-pickers-pro": "^6.9.0", "@opensearch-project/opensearch": "^2.0.0", "date-fns": "^2.30.0", "http-proxy-middleware": "^2.0.6", "material-ui-popup-state": "^5.0.9", - "next": "13.4.6", + "next": "13.4.7", "next-auth": "^4.22.1", "next-http-proxy-middleware": "^1.2.5", "nodemailer": "^6.9.3", @@ -41,18 +41,19 @@ "react-markdown": "^8.0.7", "react-polyglot": "^0.7.2", "sharp": "^0.32.1", - "swr": "^2.1.5", + "swr": "^2.2.0", + "tss-react": "^4.8.6", "uuid": "^9.0.0" }, "devDependencies": { "@babel/core": "^7.22.5", - "@types/react": "18.2.13", "@types/node": "^20.3.1", + "@types/react": "18.2.14", "@types/uuid": "^9.0.2", "babel-loader": "^9.1.2", "eslint": "^8.43.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-next": "^13.4.6", + "eslint-config-next": "^13.4.7", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jsx-a11y": "^6.7.1", diff --git a/apps/leafcutter/pages/_app.tsx b/apps/leafcutter/pages/_app.tsx deleted file mode 100644 index 0071367..0000000 --- a/apps/leafcutter/pages/_app.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable react/jsx-props-no-spreading */ -import { AppProps } from "next/app"; -import { SessionProvider } from "next-auth/react"; -import { useRouter } from "next/router"; -import Head from "next/head"; -import { CssBaseline } from "@mui/material"; -import { CacheProvider, EmotionCache } from "@emotion/react"; -import { CookiesProvider } from "react-cookie"; -import { I18n } from "react-polyglot"; -import { AdapterDateFns } from "@mui/x-date-pickers-pro/AdapterDateFns"; -import { LocalizationProvider } from "@mui/x-date-pickers-pro"; -import { AppProvider } from "components/AppProvider"; -import createEmotionCache from "lib/createEmotionCache"; -import Favicon from "images/favicon.ico"; -import en from "locales/en.json"; -import fr from "locales/fr.json"; -import "@fontsource/poppins/400.css"; -import "@fontsource/poppins/700.css"; -import "@fontsource/roboto/400.css"; -import "@fontsource/roboto/700.css"; -import "@fontsource/playfair-display/900.css"; -import "styles/global.css"; -import { LicenseInfo } from "@mui/x-data-grid-pro"; - -LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY ?? ""); - -const clientSideEmotionCache: any = createEmotionCache(); - -const messages: any = { en, fr }; - -interface LeafcutterWebProps extends AppProps { - // eslint-disable-next-line react/require-default-props - emotionCache?: EmotionCache; -} - -const LeafcutterWeb = (props: LeafcutterWebProps) => { - const { locale = "en" } = useRouter(); - const { Component, emotionCache = clientSideEmotionCache, pageProps } = props; - - return ( - <> - - - - - - - - - - - - - - - - - - - ); -}; - -export default LeafcutterWeb; diff --git a/apps/leafcutter/pages/_document.tsx b/apps/leafcutter/pages/_document.tsx deleted file mode 100644 index ec2ca90..0000000 --- a/apps/leafcutter/pages/_document.tsx +++ /dev/null @@ -1,50 +0,0 @@ -// eslint-disable-next-line no-use-before-define -import * as React from "react"; -import Document, { Html, Head, Main, NextScript } from "next/document"; -import createEmotionServer from "@emotion/server/create-instance"; -import createEmotionCache from "lib/createEmotionCache"; - -export default class LeafcutterDocument extends Document { - render() { - return ( - - - -
- - - - ); - } -} - -LeafcutterDocument.getInitialProps = async (ctx): Promise => { - const originalRenderPage = ctx.renderPage; - const cache = createEmotionCache(); - const { extractCriticalToChunks } = createEmotionServer(cache as any); - - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App: any) => (props: any) => - , - }); - - const initialProps = await Document.getInitialProps(ctx); - const emotionStyles = extractCriticalToChunks(initialProps.html); - const emotionStyleTags = emotionStyles.styles.map((style) => ( -