diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/risk/[riskId]/page.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/risk/[riskId]/page.tsx index e69099a7ea..bd83caeb93 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/risk/[riskId]/page.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/risk/[riskId]/page.tsx @@ -13,254 +13,221 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; interface PageProps { - searchParams: Promise<{ - search?: string; - status?: string; - sort?: string; - page?: string; - per_page?: string; - }>; - params: Promise<{ riskId: string; locale: string }>; + searchParams: Promise<{ + search?: string; + status?: string; + sort?: string; + page?: string; + per_page?: string; + }>; + params: Promise<{ riskId: string; locale: string }>; } export default async function RiskPage({ searchParams, params }: PageProps) { - const { riskId } = await params; - const risk = await getRisk(riskId); - - const assignees = await getAssignees(); - const t = await getI18n(); - - const { - search, - status, - sort, - page = "1", - per_page = "5", - } = await searchParams; - - const columnHeaders = await getServerColumnHeaders(); - const [column, order] = sort?.split(":") ?? []; - const hasFilters = !!(search || status); - const { tasks: loadedTasks, total } = await getTasks({ - riskId, - search, - status: status as TaskStatus, - column, - order, - page: Number.parseInt(page), - per_page: Number.parseInt(per_page), - }); - - if (!risk) { - redirect("/"); - } - - return ( -
- - - {/* - - -
- {t("risk.tasks.title")} -
-
-
- -
- - {loadedTasks.length > 0 ? ( - - ) : hasFilters ? ( - - ) : ( - <> - - - - )} -
-
-
*/} - -
- - -
-
- ); + const { riskId } = await params; + const risk = await getRisk(riskId); + + const assignees = await getAssignees(); + const t = await getI18n(); + + const { + search, + status, + sort, + page = "1", + per_page = "5", + } = await searchParams; + + const columnHeaders = await getServerColumnHeaders(); + const [column, order] = sort?.split(":") ?? []; + const hasFilters = !!(search || status); + const { tasks: loadedTasks, total } = await getTasks({ + riskId, + search, + status: status as TaskStatus, + column, + order, + page: Number.parseInt(page), + per_page: Number.parseInt(per_page), + }); + + if (!risk) { + redirect("/"); + } + + return ( +
+ + +
+ + +
+
+ ); } async function getRisk(riskId: string) { - const session = await auth.api.getSession({ - headers: await headers(), - }); - - if (!session || !session.session.activeOrganizationId) { - return null; - } - - const risk = await db.risk.findUnique({ - where: { - id: riskId, - organizationId: session.session.activeOrganizationId, - }, - include: { - assignee: { - include: { - user: true, - }, - }, - }, - }); - - return risk; + const session = await auth.api.getSession({ + headers: await headers(), + }); + + if (!session || !session.session.activeOrganizationId) { + return null; + } + + const risk = await db.risk.findUnique({ + where: { + id: riskId, + organizationId: session.session.activeOrganizationId, + }, + include: { + assignee: { + include: { + user: true, + }, + }, + }, + }); + + return risk; } async function getTasks({ - riskId, - search, - status, - column, - order, - page = 1, - per_page = 10, + riskId, + search, + status, + column, + order, + page = 1, + per_page = 10, }: { - riskId: string; - search?: string; - status?: TaskStatus; - column?: string; - order?: string; - page?: number; - per_page?: number; + riskId: string; + search?: string; + status?: TaskStatus; + column?: string; + order?: string; + page?: number; + per_page?: number; }) { - const session = await auth.api.getSession({ - headers: await headers(), - }); - - if (!session || !session.session.activeOrganizationId) { - return { tasks: [], total: 0 }; - } - - const skip = (page - 1) * per_page; - - const [tasks, total] = await Promise.all([ - db.task - .findMany({ - where: { - relatedId: riskId, - relatedType: "risk", - organizationId: session.session.activeOrganizationId, - AND: [ - search - ? { - OR: [ - { title: { contains: search, mode: "insensitive" } }, - { - description: { contains: search, mode: "insensitive" }, - }, - ], - } - : {}, - status ? { status } : {}, - ], - }, - orderBy: column - ? { - [column]: order === "asc" ? "asc" : "desc", - } - : { - createdAt: "desc", - }, - skip, - take: per_page, - include: { - assignee: { - include: { - user: true, - }, - }, - }, - }) - .then((tasks) => - tasks.map( - (task): RiskTaskType => ({ - id: task.id, - riskId: task.relatedId, - title: task.title, - status: task.status, - dueDate: task.dueDate.toISOString(), - assigneeId: task.assigneeId, - assignee: { - name: task.assignee.user.name, - image: task.assignee.user.image ?? "", - }, - }), - ), - ), - db.task.count({ - where: { - relatedId: riskId, - relatedType: "risk", - organizationId: session.session.activeOrganizationId, - AND: [ - search - ? { - OR: [ - { title: { contains: search, mode: "insensitive" } }, - { description: { contains: search, mode: "insensitive" } }, - ], - } - : {}, - status ? { status } : {}, - ], - }, - }), - ]); - - return { tasks, total }; + const session = await auth.api.getSession({ + headers: await headers(), + }); + + if (!session || !session.session.activeOrganizationId) { + return { tasks: [], total: 0 }; + } + + const skip = (page - 1) * per_page; + + const [tasks, total] = await Promise.all([ + db.task + .findMany({ + where: { + relatedId: riskId, + relatedType: "risk", + organizationId: session.session.activeOrganizationId, + AND: [ + search + ? { + OR: [ + { title: { contains: search, mode: "insensitive" } }, + { + description: { contains: search, mode: "insensitive" }, + }, + ], + } + : {}, + status ? { status } : {}, + ], + }, + orderBy: column + ? { + [column]: order === "asc" ? "asc" : "desc", + } + : { + createdAt: "desc", + }, + skip, + take: per_page, + include: { + assignee: { + include: { + user: true, + }, + }, + }, + }) + .then((tasks) => + tasks.map( + (task): RiskTaskType => ({ + id: task.id, + riskId: task.relatedId, + title: task.title, + status: task.status, + dueDate: task.dueDate.toISOString(), + assigneeId: task.assigneeId, + assignee: { + name: task.assignee.user.name, + image: task.assignee.user.image ?? "", + }, + }), + ), + ), + db.task.count({ + where: { + relatedId: riskId, + relatedType: "risk", + organizationId: session.session.activeOrganizationId, + AND: [ + search + ? { + OR: [ + { title: { contains: search, mode: "insensitive" } }, + { description: { contains: search, mode: "insensitive" } }, + ], + } + : {}, + status ? { status } : {}, + ], + }, + }), + ]); + + return { tasks, total }; } async function getAssignees() { - const session = await auth.api.getSession({ - headers: await headers(), - }); - - if (!session || !session.session.activeOrganizationId) { - return []; - } - - const assignees = await db.member.findMany({ - where: { - organizationId: session.session.activeOrganizationId, - }, - include: { - user: true, - }, - }); - - return assignees; + const session = await auth.api.getSession({ + headers: await headers(), + }); + + if (!session || !session.session.activeOrganizationId) { + return []; + } + + const assignees = await db.member.findMany({ + where: { + organizationId: session.session.activeOrganizationId, + }, + include: { + user: true, + }, + }); + + return assignees; } export async function generateMetadata({ - params, + params, }: { - params: Promise<{ locale: string }>; + params: Promise<{ locale: string }>; }): Promise { - const { locale } = await params; - setStaticParamsLocale(locale); - const t = await getI18n(); + const { locale } = await params; + setStaticParamsLocale(locale); + const t = await getI18n(); - return { - title: t("risk.risk_overview"), - }; + return { + title: t("risk.risk_overview"), + }; } diff --git a/apps/app/src/components/risks/charts/inherent-risk-chart.tsx b/apps/app/src/components/risks/charts/inherent-risk-chart.tsx index 5c4ccebe9d..c8d2146cae 100644 --- a/apps/app/src/components/risks/charts/inherent-risk-chart.tsx +++ b/apps/app/src/components/risks/charts/inherent-risk-chart.tsx @@ -5,139 +5,137 @@ import { useI18n } from "@/locales/client"; import type { Risk, Likelihood, Impact } from "@comp/db/types"; import { Button } from "@comp/ui/button"; import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, } from "@comp/ui/card"; import { - ChartContainer, - ChartTooltip, - ChartTooltipContent, + ChartContainer, + ChartTooltip, + ChartTooltipContent, } from "@comp/ui/chart"; import { PencilIcon } from "lucide-react"; import { useQueryState } from "nuqs"; import { - PolarAngleAxis, - PolarGrid, - PolarRadiusAxis, - Radar, - RadarChart, + PolarAngleAxis, + PolarGrid, + PolarRadiusAxis, + Radar, + RadarChart, } from "recharts"; const likelihoodToNumber: Record = { - very_unlikely: 1, - unlikely: 3, - possible: 5, - likely: 7, - very_likely: 10, + very_unlikely: 1, + unlikely: 3, + possible: 5, + likely: 7, + very_likely: 10, }; const impactToNumber: Record = { - insignificant: 1, - minor: 3, - moderate: 5, - major: 7, - severe: 10, + insignificant: 1, + minor: 3, + moderate: 5, + major: 7, + severe: 10, }; interface InherentRiskChartProps { - risk: Risk; + risk: Risk; } export function InherentRiskChart({ risk }: InherentRiskChartProps) { - const t = useI18n(); - const [open, setOpen] = useQueryState("inherent-risk-sheet"); + const t = useI18n(); + const [open, setOpen] = useQueryState("inherent-risk-sheet"); - const probabilityScore = likelihoodToNumber[risk.likelihood] * 10; - const impactScore = impactToNumber[risk.impact] * 10; - const inherentRisk = (probabilityScore * impactScore) / 100; + const probabilityScore = likelihoodToNumber[risk.likelihood] * 10; + const impactScore = impactToNumber[risk.impact] * 10; + const inherentRisk = (probabilityScore * impactScore) / 100; - const data = [ - { - metric: t("risk.metrics.probability"), - value: probabilityScore, - fullMark: 100, - }, - { - metric: t("risk.metrics.impact"), - value: impactScore, - fullMark: 100, - }, - { - metric: t("risk.metrics.inherentRisk"), - value: inherentRisk, - fullMark: 100, - }, - ]; + const data = [ + { + metric: t("risk.metrics.probability"), + value: probabilityScore, + fullMark: 100, + }, + { + metric: t("risk.metrics.impact"), + value: impactScore, + fullMark: 100, + }, + { + metric: t("risk.metrics.inherentRisk"), + value: inherentRisk, + fullMark: 100, + }, + ]; - const chartConfig = { - risk: { - label: t("risk.metrics.inherentRisk"), - theme: { - light: "#ef4444", - dark: "#dc2626", - }, - }, - }; + const chartConfig = { + risk: { + label: t("risk.metrics.inherentRisk"), + theme: { + light: "#ef4444", + dark: "#dc2626", + }, + }, + }; - return ( - - -
-
- -
- {t("risk.metrics.inherentRisk")} - -
-
- - {t("risk.dashboard.inherent_risk_description")} - -
-
-
- - - - - - - - } - /> - - - setOpen(null)} - /> - -
- ); + return ( + + +
+
+ + {t("risk.metrics.inherentRisk")} + + + {t("risk.dashboard.inherent_risk_description")} + +
+ +
+
+ + + + + + + + } + /> + + + setOpen(null)} + /> + +
+ ); } diff --git a/apps/app/src/components/risks/charts/residual-risk-chart.tsx b/apps/app/src/components/risks/charts/residual-risk-chart.tsx index deeb5bb085..e9078f1688 100644 --- a/apps/app/src/components/risks/charts/residual-risk-chart.tsx +++ b/apps/app/src/components/risks/charts/residual-risk-chart.tsx @@ -5,138 +5,136 @@ import { useI18n } from "@/locales/client"; import type { Risk, Likelihood, Impact } from "@comp/db/types"; import { Button } from "@comp/ui/button"; import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, } from "@comp/ui/card"; import { - ChartContainer, - ChartTooltip, - ChartTooltipContent, + ChartContainer, + ChartTooltip, + ChartTooltipContent, } from "@comp/ui/chart"; import { PencilIcon } from "lucide-react"; import { useQueryState } from "nuqs"; import { - PolarAngleAxis, - PolarGrid, - PolarRadiusAxis, - Radar, - RadarChart, + PolarAngleAxis, + PolarGrid, + PolarRadiusAxis, + Radar, + RadarChart, } from "recharts"; const likelihoodToNumber: Record = { - very_unlikely: 1, - unlikely: 3, - possible: 5, - likely: 7, - very_likely: 10, + very_unlikely: 1, + unlikely: 3, + possible: 5, + likely: 7, + very_likely: 10, }; const impactToNumber: Record = { - insignificant: 1, - minor: 3, - moderate: 5, - major: 7, - severe: 10, + insignificant: 1, + minor: 3, + moderate: 5, + major: 7, + severe: 10, }; interface ResidualRiskChartProps { - risk: Risk; + risk: Risk; } export function ResidualRiskChart({ risk }: ResidualRiskChartProps) { - const t = useI18n(); - const [open, setOpen] = useQueryState("residual-risk-sheet"); + const t = useI18n(); + const [open, setOpen] = useQueryState("residual-risk-sheet"); - const probabilityScore = likelihoodToNumber[risk.residualLikelihood] * 10; - const impactScore = impactToNumber[risk.residualImpact] * 10; - const residualRisk = (probabilityScore * impactScore) / 100; + const probabilityScore = likelihoodToNumber[risk.residualLikelihood] * 10; + const impactScore = impactToNumber[risk.residualImpact] * 10; + const residualRisk = (probabilityScore * impactScore) / 100; - const data = [ - { - metric: t("risk.metrics.probability"), - value: probabilityScore, - fullMark: 100, - }, - { - metric: t("risk.metrics.impact"), - value: impactScore, - fullMark: 100, - }, - { - metric: t("risk.metrics.residualRisk"), - value: residualRisk, - fullMark: 100, - }, - ]; + const data = [ + { + metric: t("risk.metrics.probability"), + value: probabilityScore, + fullMark: 100, + }, + { + metric: t("risk.metrics.impact"), + value: impactScore, + fullMark: 100, + }, + { + metric: t("risk.metrics.residualRisk"), + value: residualRisk, + fullMark: 100, + }, + ]; - const chartConfig = { - risk: { - label: t("risk.metrics.residualRisk"), - theme: { - light: "#ef4444", - dark: "#dc2626", - }, - }, - }; + const chartConfig = { + risk: { + label: t("risk.metrics.residualRisk"), + theme: { + light: "#ef4444", + dark: "#dc2626", + }, + }, + }; - return ( - - -
-
- -
- {t("risk.metrics.residualRisk")} - -
-
- - {t("risk.dashboard.residual_risk_description")} - -
-
-
- - - - - - - - } - /> - - - - -
- ); + return ( + + +
+
+ + {t("risk.metrics.residualRisk")} + + + {t("risk.dashboard.residual_risk_description")} + +
+ +
+
+ + + + + + + + } + /> + + + + +
+ ); }