Skip to content

Commit

Permalink
feat(src): ✨ Latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Nudelsuppe42 committed Oct 26, 2024
1 parent 3e14839 commit eb9f4e6
Show file tree
Hide file tree
Showing 52 changed files with 1,782 additions and 2,170 deletions.
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@
"format": "prettier . -w"
},
"dependencies": {
"@mantine/charts": "^7.11.1",
"@mantine/code-highlight": "^7.11.1",
"@mantine/core": "^7.11.1",
"@mantine/dates": "^7.11.1",
"@mantine/form": "^7.11.1",
"@mantine/hooks": "^7.11.1",
"@mantine/modals": "^7.11.1",
"@mantine/notifications": "^7.11.1",
"@mantine/nprogress": "^7.11.1",
"@mantine/spotlight": "^7.11.1",
"@mantine/charts": "^7.13.2",
"@mantine/code-highlight": "^7.13.2",
"@mantine/core": "^7.13.2",
"@mantine/dates": "^7.13.2",
"@mantine/form": "^7.13.2",
"@mantine/hooks": "^7.13.2",
"@mantine/modals": "^7.13.2",
"@mantine/notifications": "^7.13.2",
"@mantine/nprogress": "^7.13.2",
"@mantine/spotlight": "^7.13.2",
"@tabler/icons-react": "^3.9.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
"mantine-contextmenu": "^7.11.0",
"mantine-datatable": "^7.11.1",
"mantine-datatable": "^7.13.2",
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"next": "14.2.4",
Expand Down
Binary file added public/fonts/Minecraft.ttf
Binary file not shown.
11 changes: 11 additions & 0 deletions src/app/am/sso/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Box, Title } from "@mantine/core";

export default async function Page() {
return (
<Box ml="md" maw="50vw">
<Title order={1} mt="xl" mb="md">
SSO Configuration and Security
</Title>
</Box>
);
}
160 changes: 160 additions & 0 deletions src/app/am/sso/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import {
Badge,
Box,
Button,
Card,
Code,
NumberFormatter,
SimpleGrid,
Stack,
Table,
TableTbody,
TableTd,
TableTh,
TableThead,
TableTr,
Tabs,
TabsList,
TabsPanel,
TabsTab,
Text,
Title,
} from "@mantine/core";

import Anchor from "@/components/core/Anchor";
import { getSession } from "@/util/auth";
import { globalFetcher } from "@/util/data";

export default async function Page() {
const session = await getSession();
const realm = (await globalFetcher<[any]>(
`${process.env.NEXT_PUBLIC_KEYCLOAK_URL?.replace(
"/realms/website",
""
)}/admin/realms`,
{ headers: { Authorization: `Bearer ${session?.accessToken}` } }
))[0];
const adminEvents = await globalFetcher<any[]>(
`${process.env.NEXT_PUBLIC_KEYCLOAK_URL?.replace(
"/realms/website",
""
)}/admin/realms/website/admin-events`,
{ headers: { Authorization: `Bearer ${session?.accessToken}` } }
);
const userEvents = await globalFetcher<any[]>(
`${process.env.NEXT_PUBLIC_KEYCLOAK_URL?.replace(
"/realms/website",
""
)}/admin/realms/website/events`,
{ headers: { Authorization: `Bearer ${session?.accessToken}` } }
);
const clientStats = await globalFetcher<any[]>(
`${process.env.NEXT_PUBLIC_KEYCLOAK_URL?.replace(
"/realms/website",
""
)}/admin/realms/website/client-session-stats`,
{ headers: { Authorization: `Bearer ${session?.accessToken}` } });

return (
<Box ml="md" maw="90vw">
<Title order={1} mt="xl" mb="md">
SSO Configuration and Security
</Title>
<Tabs defaultValue="realm">
<TabsList>
<TabsTab value="realm">Realm Info</TabsTab>
<TabsTab value="adminEvents">Admin Events</TabsTab>
<TabsTab value="userEvents">User Events</TabsTab>
<TabsTab value="sessionStats">Session Stats</TabsTab>
</TabsList>

<TabsPanel value="realm">
<Stack mt="md">
{Object.keys(realm)
.map((key) => (
<Card key={key}>
<Text>
<b>{key}:</b> {typeof realm[key] === "number" ? (<NumberFormatter thousandSeparator value={realm[key]} />) : typeof realm[key] == "string"? realm[key]: <Code>{JSON.stringify(realm[key])}</Code>}
</Text>
</Card>
))}
</Stack>
</TabsPanel>
<TabsPanel value="adminEvents">
<Table mt="md">
<TableThead>
<TableTr>
<TableTh>Time</TableTh>
<TableTh>Operation</TableTh>
<TableTh>Resource Type</TableTh>
<TableTh>Resource</TableTh>
</TableTr>
</TableThead>
<TableTbody>
{adminEvents?.map((event) => (
<TableTr key={event.time}>
<TableTd>{new Date(event.time).toUTCString()}</TableTd>
<TableTd>{event.operationType}</TableTd>
<TableTd>
<Badge variant="gradient">{event.resourceType}</Badge>
</TableTd>
<TableTd>
<Anchor
href={`/am/${event.resourcePath
.split("/")
.slice(0, 2)
.join("/")}`}
>
{event.resourcePath}
</Anchor>
</TableTd>
</TableTr>
))}
</TableTbody>
</Table>
</TabsPanel>
<TabsPanel value="userEvents">
<Table mt="md">
<TableThead>
<TableTr>
<TableTh>Time</TableTh>
<TableTh>Operation</TableTh>
<TableTh>Client</TableTh>
<TableTh>User</TableTh>
</TableTr>
</TableThead>
<TableTbody>
{userEvents?.map((event) => (
<TableTr key={event.time}>
<TableTd>{new Date(event.time).toUTCString()}</TableTd>
<TableTd>{event.type}</TableTd>
<TableTd>
<Badge variant="gradient">{event.clientId}</Badge>
</TableTd>
<TableTd>{event.userId}</TableTd>
</TableTr>
))}
</TableTbody>
</Table>
</TabsPanel>
<TabsPanel value="sessionStats">
<SimpleGrid cols={{ md: 2, sm: 1 }} mt="md">
{clientStats?.map((client) => (
<Card key={client.id}>
<Title order={4}>{client.clientId}</Title>
<Text>
<b>Active: </b>{" "}
<NumberFormatter thousandSeparator value={client.active} />
</Text>
<Text>
<b>Offline: </b>{" "}
<NumberFormatter thousandSeparator value={client.offline} />
</Text>
</Card>
))}
</SimpleGrid>
</TabsPanel>
</Tabs>
</Box>
);
}
7 changes: 7 additions & 0 deletions src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { authOptions } from "@/util/auth";
import NextAuth from "next-auth";

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };

23 changes: 23 additions & 0 deletions src/app/auth/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client"

import { signIn, useSession } from "next-auth/react";

import { useRouter } from "next/navigation";
import { useEffect } from "react";

export default function SigninPage() {
const router = useRouter();
const { status } = useSession();

useEffect(() => {
if (status === "unauthenticated") {
console.log("No JWT");
console.log(status);
void signIn("keycloak", { callbackUrl: "/",redirect:true });
} else if (status === "authenticated") {
void router.push("/");
}
}, [status,router]);

return <p>Redirecting...</p>;
}
60 changes: 60 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import "@/styles/global.css";
import "@mantine/charts/styles.css";
import "@mantine/code-highlight/styles.css";
import "@mantine/core/styles.css";
import "@mantine/dates/styles.css";
import "@mantine/notifications/styles.css";
import "@mantine/nprogress/styles.css";
import "@mantine/spotlight/styles.css";
import "mantine-datatable/styles.layer.css";

import { ColorSchemeScript, MantineProvider } from "@mantine/core";

import AuthProvider from "@/components/AuthProvider";
import SWRSetup from "@/components/core/SWRSetup";
import AppLayout from "@/components/layout";
import { getSession } from "@/util/auth";
import { Notifications } from "@mantine/notifications";
import { Inter } from "next/font/google";
import localFont from "next/font/local";

export const interFont = Inter({
subsets: ["latin"],
variable: "--font-inter",
});
export const minecraftFont = localFont({
src: "../../public/fonts/Minecraft.ttf",
weight: "100 900",
display: "swap",
style: "normal",
variable: "--font-minecraft",
});

export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getSession();

return (
<html
lang="en"
className={`${interFont.variable} ${minecraftFont.variable}`}
>
<head>
<ColorSchemeScript />
</head>
<body>
<MantineProvider>
<AuthProvider session={session}>
<SWRSetup>
<Notifications limit={3} />
<AppLayout>{children}</AppLayout>
</SWRSetup>
</AuthProvider>
</MantineProvider>
</body>
</html>
);
}
22 changes: 22 additions & 0 deletions src/app/me/connections/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Box, Skeleton, Text, Title } from "@mantine/core";

export default async function Page() {

return (
<Box ml="md" maw="50vw">
<Title order={1} mt="xl" mb="md">
Your Social Accounts
</Title>
<Skeleton mb="md">
<Text fw={"bold"}>Loading...</Text>
<br />
<Text fz="sm">Loading...</Text>
</Skeleton>
<Skeleton>
<Text fw={"bold"}>Loading...</Text>
<br />
<Text fz="sm">Loading...</Text>
</Skeleton>
</Box>
);
}
20 changes: 20 additions & 0 deletions src/app/me/connections/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Box, Title } from '@mantine/core';

import { SocialAccountStack } from "@/components/data/SocialAccount";
import { getUser } from "@/hooks/useUser";
import { KeycloakUser } from "@/types/User";
import { authedFetcher } from "@/util/data";

export default async function Page() {
const user = await getUser();
const data = await authedFetcher<KeycloakUser>(`/users/${user.id}/kc`);

return (
<Box ml="md" maw="50vw">
<Title order={1} mt="xl" mb="md">
Your Social Accounts
</Title>
<SocialAccountStack identities={data.federatedIdentities} withUnlinked />
</Box>
);
}
Loading

0 comments on commit eb9f4e6

Please sign in to comment.