From 91e23268268351e8d05cb978614bf21d7d91b842 Mon Sep 17 00:00:00 2001 From: gearnode Date: Sun, 9 Feb 2025 21:24:18 -0800 Subject: [PATCH] Add frameworks page Signed-off-by: gearnode --- apps/console/src/App.tsx | 2 + apps/console/src/components/AppSidebar.tsx | 5 + apps/console/src/components/ui/card.tsx | 76 ++++++++++++ apps/console/src/pages/FrameworksPage.tsx | 129 +++++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 apps/console/src/components/ui/card.tsx create mode 100644 apps/console/src/pages/FrameworksPage.tsx diff --git a/apps/console/src/App.tsx b/apps/console/src/App.tsx index 7e2c039b8..bbe8b57fe 100644 --- a/apps/console/src/App.tsx +++ b/apps/console/src/App.tsx @@ -24,6 +24,7 @@ const HomePage = lazy(() => import("./pages/HomePage")); const NotFoundPage = lazy(() => import("./pages/NotFoundPage")); const PeoplesPage = lazy(() => import("./pages/PeoplesPage")); const VendorsPage = lazy(() => import("./pages/VendorsPage")); +const FrameworksPage = lazy(() => import("./pages/FrameworksPage")); function App() { return ( @@ -39,6 +40,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/apps/console/src/components/AppSidebar.tsx b/apps/console/src/components/AppSidebar.tsx index 9226f925e..a8e45c23b 100644 --- a/apps/console/src/components/AppSidebar.tsx +++ b/apps/console/src/components/AppSidebar.tsx @@ -36,6 +36,11 @@ const staticData = { avatar: "/avatars/shadcn.jpg", }, navMain: [ + { + title: "Frameworks", + url: "/frameworks", + icon: BookOpen, + }, { title: "Peoples", url: "/peoples", diff --git a/apps/console/src/components/ui/card.tsx b/apps/console/src/components/ui/card.tsx new file mode 100644 index 000000000..cabfbfc59 --- /dev/null +++ b/apps/console/src/components/ui/card.tsx @@ -0,0 +1,76 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/apps/console/src/pages/FrameworksPage.tsx b/apps/console/src/pages/FrameworksPage.tsx new file mode 100644 index 000000000..96130bb35 --- /dev/null +++ b/apps/console/src/pages/FrameworksPage.tsx @@ -0,0 +1,129 @@ +import { Suspense, useEffect } from "react"; +import { + graphql, + PreloadedQuery, + usePreloadedQuery, + useQueryLoader, +} from "react-relay"; +import { Globe2, CheckCircle } from "lucide-react"; +import { Card, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import type { FrameworksPageQuery as FrameworksPageQueryType } from "./__generated__/FrameworksPageQuery.graphql"; + +const FrameworksPageQuery = graphql` + query FrameworksPageQuery { + node(id: "AZSfP_xAcAC5IAAAAAAltA") { + id + ... on Organization { + frameworks { + edges { + node { + id + name + description + controls { + edges { + node { + id + state + } + } + } + createdAt + updatedAt + } + } + } + } + } + } +`; + +function FrameworksPageContent({ + queryRef, +}: { + queryRef: PreloadedQuery; +}) { + const data = usePreloadedQuery(FrameworksPageQuery, queryRef); + const frameworks = data.node.frameworks?.edges.map(edge => edge?.node) ?? []; + + return ( +
+
+

Framework

+

+ Compliance frameworks like SOC 2 and ISO 27001 provide guidelines to secure sensitive data, manage risks, and + build trust. SOC 2 focuses on customer data protection via five Trust Principles, while ISO 27001 establishes + a comprehensive Information Security Management System for global standards. +

+
+ +
+ {frameworks.map((framework) => ( + + +
+ + Active + +
+ +
{framework?.name}
+
+

{framework?.name}

+

+ {framework?.description} +

+
+
+
+ + {framework?.controls?.edges.length} Controls +
+
+
+
+ ))} +
+
+ ); +} + +function FrameworksPageFallback() { + return ( +
+
+
+
+
+
+ {[1, 2].map((i) => ( + + +
+
+
+
+
+
+ + + ))} +
+
+ ); +} + +export default function FrameworksPage() { + const [queryRef, loadQuery] = useQueryLoader(FrameworksPageQuery); + + useEffect(() => { + loadQuery({}); + }, [loadQuery]); + + return ( + }> + {queryRef && } + + ); +}