diff --git a/actions/compliance.ts b/actions/compliance.ts
new file mode 100644
index 0000000000..76064ebb33
--- /dev/null
+++ b/actions/compliance.ts
@@ -0,0 +1,39 @@
+"use server";
+
+import { revalidatePath } from "next/cache";
+import { redirect } from "next/navigation";
+
+import { parseStringify } from "@/lib";
+
+export const getCompliance = async ({ page = 1 }) => {
+ if (isNaN(Number(page)) || page < 1) redirect("/compliance");
+ const keyServer = process.env.LOCAL_SITE_URL;
+
+ try {
+ const compliance = await fetch(
+ `${keyServer}/api/compliance?page%5Bnumber%5D=${page}`,
+ );
+ const data = await compliance.json();
+ const parsedData = parseStringify(data);
+ revalidatePath("/compliance");
+ return parsedData;
+ } catch (error) {
+ console.error("Error fetching Compliance:", error);
+ return undefined;
+ }
+};
+
+export const getErrorMessage = (error: unknown): string => {
+ let message: string;
+
+ if (error instanceof Error) {
+ message = error.message;
+ } else if (error && typeof error === "object" && "message" in error) {
+ message = String(error.message);
+ } else if (typeof error === "string") {
+ message = error;
+ } else {
+ message = "Wops! Something when wrong.";
+ }
+ return message;
+};
diff --git a/app/(prowler)/compliance/page.tsx b/app/(prowler)/compliance/page.tsx
index 59b39ea737..e610187e06 100644
--- a/app/(prowler)/compliance/page.tsx
+++ b/app/(prowler)/compliance/page.tsx
@@ -1,13 +1,53 @@
-import React from "react";
+import { Spacer } from "@nextui-org/react";
+import { redirect } from "next/navigation";
+import { Suspense } from "react";
+import { getCompliance } from "@/actions/compliance";
+import {
+ ComplianceCard,
+ ComplianceSkeletonGrid,
+} from "@/components/compliance";
+import { FilterControls } from "@/components/filters";
import { Header } from "@/components/ui";
+import { searchParamsProps } from "@/types";
-export default function Compliance() {
+export default async function Compliance({ searchParams }: searchParamsProps) {
return (
<>
-
-
Hi hi from Compliance page
+
+
+
+ }>
+
+
>
);
}
+
+const SSRComplianceGrid = async ({ searchParams }: searchParamsProps) => {
+ const page = searchParams.page ? parseInt(searchParams.page) : 1;
+ const compliancesData = await getCompliance({ page });
+ const [compliances] = await Promise.all([compliancesData]);
+
+ if (compliances?.errors) redirect("/compliance");
+
+ return (
+
+ {compliances.compliance?.data.map((compliance: any) => (
+
+ ))}
+
+ );
+};
diff --git a/app/api/compliance/route.ts b/app/api/compliance/route.ts
new file mode 100644
index 0000000000..b2e4a01d9f
--- /dev/null
+++ b/app/api/compliance/route.ts
@@ -0,0 +1,10 @@
+import { NextResponse } from "next/server";
+
+import data from "../../../dataCompliance.json";
+
+export async function GET() {
+ // Simulate fetching data with a delay
+ await new Promise((resolve) => setTimeout(resolve, 2000));
+
+ return NextResponse.json({ compliance: data });
+}
diff --git a/components/compliance/ComplianceCard.tsx b/components/compliance/ComplianceCard.tsx
new file mode 100644
index 0000000000..32e8004377
--- /dev/null
+++ b/components/compliance/ComplianceCard.tsx
@@ -0,0 +1,85 @@
+import { Card, CardBody, Progress } from "@nextui-org/react";
+import Image from "next/image";
+import React from "react";
+
+import { getComplianceIcon } from "../icons";
+
+interface ComplianceCardProps {
+ title: string;
+ passingRequirements: number;
+ totalRequirements: number;
+ prevPassingRequirements: number;
+ prevTotalRequirements: number;
+}
+
+export const ComplianceCard: React.FC = ({
+ title,
+ passingRequirements,
+ totalRequirements,
+ prevPassingRequirements,
+ prevTotalRequirements,
+}) => {
+ const ratingPercentage = Math.floor(
+ (passingRequirements / totalRequirements) * 100,
+ );
+
+ const prevRatingPercentage = Math.floor(
+ (prevPassingRequirements / prevTotalRequirements) * 100,
+ );
+
+ const getScanChange = () => {
+ const scanDifference = ratingPercentage - prevRatingPercentage;
+ if (scanDifference < 0 && scanDifference <= -1) {
+ return `${scanDifference}% from last scan`;
+ }
+ if (scanDifference > 0 && scanDifference >= 1) {
+ return `+${scanDifference}% from last scan`;
+ }
+ return "No change from last scan";
+ };
+
+ const getRatingColor = (ratingPercentage: number) => {
+ if (ratingPercentage <= 10) {
+ return "danger";
+ }
+ if (ratingPercentage <= 40) {
+ return "warning";
+ }
+ return "success";
+ };
+
+ return (
+
+
+
+
+
+
{title}
+
+
+
+
+ {passingRequirements} / {totalRequirements}
+
+ Passing Requirements
+
+ {getScanChange()}
+
+
+
+
+
+ );
+};
diff --git a/components/compliance/ComplianceSkeletonGrid.tsx b/components/compliance/ComplianceSkeletonGrid.tsx
new file mode 100644
index 0000000000..c16d3edca9
--- /dev/null
+++ b/components/compliance/ComplianceSkeletonGrid.tsx
@@ -0,0 +1,18 @@
+import { Card, Skeleton } from "@nextui-org/react";
+import React from "react";
+
+export const ComplianceSkeletonGrid = () => {
+ return (
+
+
+ {[...Array(28)].map((_, index) => (
+
+ ))}
+
+
+ );
+};
diff --git a/components/compliance/index.ts b/components/compliance/index.ts
new file mode 100644
index 0000000000..6f025f2ca5
--- /dev/null
+++ b/components/compliance/index.ts
@@ -0,0 +1,2 @@
+export * from "./ComplianceCard";
+export * from "./ComplianceSkeletonGrid";
diff --git a/components/filters/CustomCheckboxMutedFindings.tsx b/components/filters/CustomCheckboxMutedFindings.tsx
index 0ebfcb7755..62715403fe 100644
--- a/components/filters/CustomCheckboxMutedFindings.tsx
+++ b/components/filters/CustomCheckboxMutedFindings.tsx
@@ -1,10 +1,20 @@
import { Checkbox } from "@nextui-org/react";
import React from "react";
-export const CustomCheckboxMutedFindings = () => {
+interface CustomCheckboxMutedFindingsProps {
+ mutedFindings?: boolean;
+}
+
+export const CustomCheckboxMutedFindings: React.FC<
+ CustomCheckboxMutedFindingsProps
+> = ({ mutedFindings }) => {
return (
-
- Include Muted Findings
-
+ <>
+ {mutedFindings && (
+
+ Include Muted Findings
+
+ )}
+ >
);
};
diff --git a/components/filters/FilterControls.tsx b/components/filters/FilterControls.tsx
index 5ec7fe418a..e087d3c108 100644
--- a/components/filters/FilterControls.tsx
+++ b/components/filters/FilterControls.tsx
@@ -1,15 +1,23 @@
+import React from "react";
+
import { CustomAccountSelection } from "./CustomAccountSelection";
import { CustomCheckboxMutedFindings } from "./CustomCheckboxMutedFindings";
import { CustomDatePicker } from "./CustomDatePicker";
import { CustomSelectProvider } from "./CustomSelectProvider";
-export const FilterControls = () => {
+interface FilterControlsProps {
+ mutedFindings?: boolean;
+}
+
+export const FilterControls: React.FC = ({
+ mutedFindings = true,
+}) => {
return (
-
+
);
};
diff --git a/components/icons/compliance/IconCompliance.tsx b/components/icons/compliance/IconCompliance.tsx
new file mode 100644
index 0000000000..543f6c68c8
--- /dev/null
+++ b/components/icons/compliance/IconCompliance.tsx
@@ -0,0 +1,63 @@
+import AWSLogo from "./aws.svg";
+import CISLogo from "./cis.svg";
+import CISALogo from "./cisa.svg";
+import ENSLogo from "./ens.png";
+import FedRAMPLogo from "./fedramp.svg";
+import FFIECLogo from "./ffiec.svg";
+import GDPRLogo from "./gdpr.svg";
+import GxPLogo from "./gxp-aws.svg";
+import HIPAALogo from "./hipaa.svg";
+import ISOLogo from "./iso-27001.svg";
+import MITRELogo from "./mitre-attack.svg";
+import NISTLogo from "./nist.svg";
+import PCILogo from "./pci-dss.svg";
+import RBILogo from "./rbi.svg";
+import SOC2Logo from "./soc2.svg";
+
+export const getComplianceIcon = (complianceTitle: string) => {
+ if (complianceTitle.toLowerCase().includes("aws")) {
+ return AWSLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("cisa")) {
+ return CISALogo;
+ }
+ if (complianceTitle.toLowerCase().includes("cis")) {
+ return CISLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("ens")) {
+ return ENSLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("ffiec")) {
+ return FFIECLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("fedramp")) {
+ return FedRAMPLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("gdpr")) {
+ return GDPRLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("gxp")) {
+ return GxPLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("hipaa")) {
+ return HIPAALogo;
+ }
+ if (complianceTitle.toLowerCase().includes("iso")) {
+ return ISOLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("mitre")) {
+ return MITRELogo;
+ }
+ if (complianceTitle.toLowerCase().includes("nist")) {
+ return NISTLogo;
+ }
+ if (complianceTitle.toLowerCase().includes("pci")) {
+ return PCILogo;
+ }
+ if (complianceTitle.toLowerCase().includes("rbi")) {
+ return RBILogo;
+ }
+ if (complianceTitle.toLowerCase().includes("soc2")) {
+ return SOC2Logo;
+ }
+};
diff --git a/components/icons/compliance/aws.svg b/components/icons/compliance/aws.svg
new file mode 100644
index 0000000000..4715937ff0
--- /dev/null
+++ b/components/icons/compliance/aws.svg
@@ -0,0 +1,38 @@
+
+
+
diff --git a/components/icons/compliance/cis.svg b/components/icons/compliance/cis.svg
new file mode 100644
index 0000000000..013f35a75e
--- /dev/null
+++ b/components/icons/compliance/cis.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/cisa.svg b/components/icons/compliance/cisa.svg
new file mode 100644
index 0000000000..c26f681d51
--- /dev/null
+++ b/components/icons/compliance/cisa.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/components/icons/compliance/ens.png b/components/icons/compliance/ens.png
new file mode 100644
index 0000000000..c3e6433f31
Binary files /dev/null and b/components/icons/compliance/ens.png differ
diff --git a/components/icons/compliance/fedramp.svg b/components/icons/compliance/fedramp.svg
new file mode 100644
index 0000000000..7706bd4eff
--- /dev/null
+++ b/components/icons/compliance/fedramp.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/ffiec.svg b/components/icons/compliance/ffiec.svg
new file mode 100644
index 0000000000..40951851e9
--- /dev/null
+++ b/components/icons/compliance/ffiec.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/gdpr.svg b/components/icons/compliance/gdpr.svg
new file mode 100644
index 0000000000..31175e9afe
--- /dev/null
+++ b/components/icons/compliance/gdpr.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/gxp-aws.svg b/components/icons/compliance/gxp-aws.svg
new file mode 100644
index 0000000000..7b22b53de3
--- /dev/null
+++ b/components/icons/compliance/gxp-aws.svg
@@ -0,0 +1,455 @@
+
+
+
diff --git a/components/icons/compliance/hipaa.svg b/components/icons/compliance/hipaa.svg
new file mode 100644
index 0000000000..b9537032f6
--- /dev/null
+++ b/components/icons/compliance/hipaa.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/iso-27001.svg b/components/icons/compliance/iso-27001.svg
new file mode 100644
index 0000000000..109c19521d
--- /dev/null
+++ b/components/icons/compliance/iso-27001.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/mitre-attack.svg b/components/icons/compliance/mitre-attack.svg
new file mode 100644
index 0000000000..c546eedd83
--- /dev/null
+++ b/components/icons/compliance/mitre-attack.svg
@@ -0,0 +1,315 @@
+
+
+
diff --git a/components/icons/compliance/nist.svg b/components/icons/compliance/nist.svg
new file mode 100644
index 0000000000..4231017c94
--- /dev/null
+++ b/components/icons/compliance/nist.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/components/icons/compliance/pci-dss.svg b/components/icons/compliance/pci-dss.svg
new file mode 100644
index 0000000000..52f93be38b
--- /dev/null
+++ b/components/icons/compliance/pci-dss.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/compliance/rbi.svg b/components/icons/compliance/rbi.svg
new file mode 100644
index 0000000000..ce1d81f83d
--- /dev/null
+++ b/components/icons/compliance/rbi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/components/icons/compliance/soc2.svg b/components/icons/compliance/soc2.svg
new file mode 100644
index 0000000000..d2b8782541
--- /dev/null
+++ b/components/icons/compliance/soc2.svg
@@ -0,0 +1,9 @@
+
diff --git a/components/icons/index.ts b/components/icons/index.ts
index c057522527..7912d466fd 100644
--- a/components/icons/index.ts
+++ b/components/icons/index.ts
@@ -1,3 +1,4 @@
+export * from "./compliance/IconCompliance";
export * from "./Icons";
export * from "./prowler/ProwlerIcons";
export * from "./services/IconServices";
diff --git a/dataCompliance.json b/dataCompliance.json
new file mode 100644
index 0000000000..a1bdd62831
--- /dev/null
+++ b/dataCompliance.json
@@ -0,0 +1,438 @@
+{
+ "links": {
+ "first": "http://localhost:8080/api/v1/compliance?page%5Bnumber%5D=1",
+ "last": "http://localhost:8080/api/v1/compliance?page%5Bnumber%5D=1",
+ "next": null,
+ "prev": null
+ },
+ "data": [
+ {
+ "id": "001",
+ "attributes": {
+ "title": "AWS Account Security Onboarding",
+ "passingRequirements": 28,
+ "totalRequirements": 83,
+ "regions": ["us-east-1", "us-east-2"]
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 28,
+ "totalRequirements": 83
+ }
+ }
+ },
+ {
+ "id": "002",
+ "attributes": {
+ "title": "AWS Audit Manager Control Tower Guardrails",
+ "passingRequirements": 10,
+ "totalRequirements": 14,
+ "regions": ["us-west-1", "us-west-2"]
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 14,
+ "totalRequirements": 14
+ }
+ }
+ },
+ {
+ "id": "003",
+ "attributes": {
+ "title": "AWS Foundational Security Best Practices",
+ "passingRequirements": 22,
+ "totalRequirements": 37,
+ "regions": ["eu-west-1", "eu-west-2"]
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 22,
+ "totalRequirements": 37
+ }
+ }
+ },
+ {
+ "id": "004",
+ "attributes": {
+ "title": "AWS Foundational Technical Review",
+ "passingRequirements": 3,
+ "totalRequirements": 45,
+ "regions": ["ap-southeast-1", "ap-southeast-2"]
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 25,
+ "totalRequirements": 45
+ }
+ }
+ },
+ {
+ "id": "005",
+ "attributes": {
+ "title": "AWS Well Architected Framework Reliability Pillar",
+ "passingRequirements": 2,
+ "totalRequirements": 3,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 0,
+ "totalRequirements": 3
+ }
+ }
+ },
+ {
+ "id": "006",
+ "attributes": {
+ "title": "AWS Well Architected Framework Security Pillar",
+ "passingRequirements": 19,
+ "totalRequirements": 57,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 24,
+ "totalRequirements": 57
+ }
+ }
+ },
+ {
+ "id": "007",
+ "attributes": {
+ "title": "CIS 1.4",
+ "passingRequirements": 43,
+ "totalRequirements": 58,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 40,
+ "totalRequirements": 58
+ }
+ }
+ },
+ {
+ "id": "008",
+ "attributes": {
+ "title": "CIS 1.5",
+ "passingRequirements": 48,
+ "totalRequirements": 63,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 50,
+ "totalRequirements": 63
+ }
+ }
+ },
+ {
+ "id": "009",
+ "attributes": {
+ "title": "CIS 2.0",
+ "passingRequirements": 47,
+ "totalRequirements": 64,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 64,
+ "totalRequirements": 64
+ }
+ }
+ },
+ {
+ "id": "010",
+ "attributes": {
+ "title": "CIS 3.0",
+ "passingRequirements": 45,
+ "totalRequirements": 62,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 48,
+ "totalRequirements": 62
+ }
+ }
+ },
+ {
+ "id": "011",
+ "attributes": {
+ "title": "CISA",
+ "passingRequirements": 4,
+ "totalRequirements": 16,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 4,
+ "totalRequirements": 16
+ }
+ }
+ },
+ {
+ "id": "012",
+ "attributes": {
+ "title": "ENS RD2022 CategorÃa ALTA",
+ "passingRequirements": 89,
+ "totalRequirements": 189,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 82,
+ "totalRequirements": 189
+ }
+ }
+ },
+ {
+ "id": "013",
+ "attributes": {
+ "title": "FFIEC",
+ "passingRequirements": 8,
+ "totalRequirements": 44,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 40,
+ "totalRequirements": 44
+ }
+ }
+ },
+ {
+ "id": "014",
+ "attributes": {
+ "title": "FedRAMP Low Revision 4",
+ "passingRequirements": 4,
+ "totalRequirements": 18,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 4,
+ "totalRequirements": 18
+ }
+ }
+ },
+ {
+ "id": "015",
+ "attributes": {
+ "title": "FedRamp Moderate Revision 4",
+ "passingRequirements": 11,
+ "totalRequirements": 64,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 28,
+ "totalRequirements": 64
+ }
+ }
+ },
+ {
+ "id": "016",
+ "attributes": {
+ "title": "GDPR",
+ "passingRequirements": 0,
+ "totalRequirements": 3,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 0,
+ "totalRequirements": 3
+ }
+ }
+ },
+ {
+ "id": "017",
+ "attributes": {
+ "title": "GxP 21 CFR Part 11",
+ "passingRequirements": 1,
+ "totalRequirements": 11,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 11,
+ "totalRequirements": 11
+ }
+ }
+ },
+ {
+ "id": "018",
+ "attributes": {
+ "title": "GxP EU Annex 11",
+ "passingRequirements": 5,
+ "totalRequirements": 14,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 5,
+ "totalRequirements": 14
+ }
+ }
+ },
+ {
+ "id": "019",
+ "attributes": {
+ "title": "HIPAA",
+ "passingRequirements": 2,
+ "totalRequirements": 32,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 9,
+ "totalRequirements": 32
+ }
+ }
+ },
+ {
+ "id": "020",
+ "attributes": {
+ "title": "ISO27001 2013",
+ "passingRequirements": 55,
+ "totalRequirements": 79,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 66,
+ "totalRequirements": 79
+ }
+ }
+ },
+ {
+ "id": "021",
+ "attributes": {
+ "title": "MITRE ATTACK",
+ "passingRequirements": 7,
+ "totalRequirements": 46,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 19,
+ "totalRequirements": 46
+ }
+ }
+ },
+ {
+ "id": "022",
+ "attributes": {
+ "title": "NIST 800 171 Revision 2",
+ "passingRequirements": 3,
+ "totalRequirements": 50,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 3,
+ "totalRequirements": 50
+ }
+ }
+ },
+ {
+ "id": "023",
+ "attributes": {
+ "title": "NIST 800 53 Revision 4",
+ "passingRequirements": 21,
+ "totalRequirements": 64,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 21,
+ "totalRequirements": 64
+ }
+ }
+ },
+ {
+ "id": "024",
+ "attributes": {
+ "title": "NIST 800 53 Revision 5",
+ "passingRequirements": 75,
+ "totalRequirements": 288,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 75,
+ "totalRequirements": 288
+ }
+ }
+ },
+ {
+ "id": "025",
+ "attributes": {
+ "title": "NIST CSF 1.1",
+ "passingRequirements": 15,
+ "totalRequirements": 56,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 46,
+ "totalRequirements": 56
+ }
+ }
+ },
+ {
+ "id": "026",
+ "attributes": {
+ "title": "PCI 3.2.1",
+ "passingRequirements": 11,
+ "totalRequirements": 19,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 19,
+ "totalRequirements": 19
+ }
+ }
+ },
+ {
+ "id": "027",
+ "attributes": {
+ "title": "RBI Cyber Security Framework",
+ "passingRequirements": 3,
+ "totalRequirements": 9,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 3,
+ "totalRequirements": 9
+ }
+ }
+ },
+ {
+ "id": "028",
+ "attributes": {
+ "title": "SOC2",
+ "passingRequirements": 7,
+ "totalRequirements": 56,
+ "regions": []
+ },
+ "lastScan": {
+ "attributes": {
+ "passingRequirements": 7,
+ "totalRequirements": 56
+ }
+ }
+ }
+ ],
+ "meta": {
+ "pagination": {
+ "page": 1,
+ "pages": 1,
+ "count": 28
+ },
+ "version": "v1"
+ }
+}
diff --git a/images.d.ts b/images.d.ts
new file mode 100644
index 0000000000..ad238adbf8
--- /dev/null
+++ b/images.d.ts
@@ -0,0 +1,29 @@
+declare module "*.png" {
+ const value: string;
+ export default value;
+}
+
+declare module "*.jpg" {
+ const value: string;
+ export default value;
+}
+
+declare module "*.jpeg" {
+ const value: string;
+ export default value;
+}
+
+declare module "*.gif" {
+ const value: string;
+ export default value;
+}
+
+declare module "*.svg" {
+ const content: any;
+ export default content;
+}
+
+declare module "*.webp" {
+ const value: string;
+ export default value;
+}
diff --git a/tsconfig.json b/tsconfig.json
index f204766d1b..0a3c1cf1de 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -25,5 +25,11 @@
"target": "es5"
},
"exclude": ["node_modules"],
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"]
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ "images.d.ts"
+ ]
}