From 6e5088e79cb8f220ec07f4fe0f7af0baf8f80301 Mon Sep 17 00:00:00 2001
From: Karume-lab <danielkarume@outlook.com>
Date: Thu, 6 Jun 2024 12:39:07 +0300
Subject: [PATCH 1/2] feat: :sparkles: embedding superset

succesfully embedded superset dashboard using embed id
---
 package-lock.json                          | 120 +++-
 package.json                               |   2 +
 src/app/dashboard/innovation/[id]/page.tsx | 678 ++++++++++++---------
 superset-embed                             |   1 +
 4 files changed, 504 insertions(+), 297 deletions(-)
 create mode 160000 superset-embed

diff --git a/package-lock.json b/package-lock.json
index 4fb9ba9..74ee974 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,9 @@
         "@radix-ui/react-toast": "^1.1.5",
         "@radix-ui/themes": "^3.0.3",
         "@reduxjs/toolkit": "^2.2.3",
+        "@superset-ui/embedded-sdk": "^0.1.0-alpha.11",
         "async-mutex": "^0.5.0",
+        "axios": "^1.7.2",
         "class-variance-authority": "^0.7.0",
         "clsx": "^2.1.1",
         "lucide-react": "^0.377.0",
@@ -7371,6 +7373,22 @@
         "url": "https://opencollective.com/storybook"
       }
     },
+    "node_modules/@superset-ui/embedded-sdk": {
+      "version": "0.1.0-alpha.11",
+      "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.11.tgz",
+      "integrity": "sha512-TYD7eLyk5csN5/ms723Oz6oE/jtk5tqp7smub+K/GSPZWy1aArLbWcEp0ARDdqLzRkRpc3gxEwCWDHs3IERAPg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@superset-ui/switchboard": "^0.18.26-0",
+        "jwt-decode": "^3.1.2"
+      }
+    },
+    "node_modules/@superset-ui/switchboard": {
+      "version": "0.18.26-2",
+      "resolved": "https://registry.npmjs.org/@superset-ui/switchboard/-/switchboard-0.18.26-2.tgz",
+      "integrity": "sha512-yIuEv8QGS+j+SS3P3TGQ0wp9WGKGHJrI39kjh74N1HFZlHhfZEKZ28XdZIjOEXlqCr7pvrF0XPEzLHnGSsbtCg==",
+      "license": "Apache-2.0"
+    },
     "node_modules/@swc/counter": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
@@ -9397,8 +9415,7 @@
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "dev": true
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "node_modules/available-typed-arrays": {
       "version": "1.0.7",
@@ -9424,6 +9441,17 @@
         "node": ">=4"
       }
     },
+    "node_modules/axios": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/axobject-query": {
       "version": "3.2.1",
       "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -10840,7 +10868,6 @@
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
       "dependencies": {
         "delayed-stream": "~1.0.0"
       },
@@ -11615,7 +11642,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
       "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "dev": true,
       "engines": {
         "node": ">=0.4.0"
       }
@@ -13517,6 +13543,26 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/for-each": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -13683,7 +13729,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
       "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
-      "dev": true,
       "dependencies": {
         "asynckit": "^0.4.0",
         "combined-stream": "^1.0.8",
@@ -17527,6 +17572,12 @@
         "node": ">=4.0"
       }
     },
+    "node_modules/jwt-decode": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
+      "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==",
+      "license": "MIT"
+    },
     "node_modules/keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -17978,7 +18029,6 @@
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -17987,7 +18037,6 @@
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "dependencies": {
         "mime-db": "1.52.0"
       },
@@ -19674,6 +19723,12 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
+    },
     "node_modules/psl": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -28428,6 +28483,20 @@
         "file-system-cache": "2.3.0"
       }
     },
+    "@superset-ui/embedded-sdk": {
+      "version": "0.1.0-alpha.11",
+      "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.11.tgz",
+      "integrity": "sha512-TYD7eLyk5csN5/ms723Oz6oE/jtk5tqp7smub+K/GSPZWy1aArLbWcEp0ARDdqLzRkRpc3gxEwCWDHs3IERAPg==",
+      "requires": {
+        "@superset-ui/switchboard": "^0.18.26-0",
+        "jwt-decode": "^3.1.2"
+      }
+    },
+    "@superset-ui/switchboard": {
+      "version": "0.18.26-2",
+      "resolved": "https://registry.npmjs.org/@superset-ui/switchboard/-/switchboard-0.18.26-2.tgz",
+      "integrity": "sha512-yIuEv8QGS+j+SS3P3TGQ0wp9WGKGHJrI39kjh74N1HFZlHhfZEKZ28XdZIjOEXlqCr7pvrF0XPEzLHnGSsbtCg=="
+    },
     "@swc/counter": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
@@ -30062,8 +30131,7 @@
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "dev": true
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "available-typed-arrays": {
       "version": "1.0.7",
@@ -30080,6 +30148,16 @@
       "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==",
       "dev": true
     },
+    "axios": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+      "requires": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "axobject-query": {
       "version": "3.2.1",
       "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@@ -31136,7 +31214,6 @@
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
       "requires": {
         "delayed-stream": "~1.0.0"
       }
@@ -31731,8 +31808,7 @@
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "dev": true
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
     },
     "depd": {
       "version": "2.0.0",
@@ -33244,6 +33320,11 @@
       "integrity": "sha512-s04193L4JE+ntEcQXbD6jxRRlyj9QXcgEl2W6xSjH4l9x4b0eHoCHfbYHjqf9LdZFUiM5LhgpiqsvLj/AyOyYQ==",
       "dev": true
     },
+    "follow-redirects": {
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
+    },
     "for-each": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -33364,7 +33445,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
       "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
-      "dev": true,
       "requires": {
         "asynckit": "^0.4.0",
         "combined-stream": "^1.0.8",
@@ -36101,6 +36181,11 @@
         "object.values": "^1.1.6"
       }
     },
+    "jwt-decode": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
+      "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
+    },
     "keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -36452,14 +36537,12 @@
     "mime-db": {
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
     },
     "mime-types": {
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "requires": {
         "mime-db": "1.52.0"
       }
@@ -37623,6 +37706,11 @@
         "ipaddr.js": "1.9.1"
       }
     },
+    "proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
     "psl": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
diff --git a/package.json b/package.json
index ea6c1ea..5670e09 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,9 @@
     "@radix-ui/react-toast": "^1.1.5",
     "@radix-ui/themes": "^3.0.3",
     "@reduxjs/toolkit": "^2.2.3",
+    "@superset-ui/embedded-sdk": "^0.1.0-alpha.11",
     "async-mutex": "^0.5.0",
+    "axios": "^1.7.2",
     "class-variance-authority": "^0.7.0",
     "clsx": "^2.1.1",
     "lucide-react": "^0.377.0",
diff --git a/src/app/dashboard/innovation/[id]/page.tsx b/src/app/dashboard/innovation/[id]/page.tsx
index 56d4078..9524909 100644
--- a/src/app/dashboard/innovation/[id]/page.tsx
+++ b/src/app/dashboard/innovation/[id]/page.tsx
@@ -2,63 +2,65 @@
 import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
 import { Button } from "@/components/ui/button";
 import {
-	DropdownMenu,
-	DropdownMenuContent,
-	DropdownMenuItem,
-	DropdownMenuTrigger,
+  DropdownMenu,
+  DropdownMenuContent,
+  DropdownMenuItem,
+  DropdownMenuTrigger,
 } from "@/components/ui/dropdown-menu";
 import {
-	Form,
-	FormField,
-	FormItem,
-	FormLabel,
-	FormControl,
-	FormMessage,
+  Form,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormControl,
+  FormMessage,
 } from "@/components/ui/form";
 import { Separator } from "@/components/ui/separator";
 import { Textarea } from "@/components/ui/textarea";
 import { useToast } from "@/components/ui/use-toast";
 import { zodResolver } from "@hookform/resolvers/zod";
 import {
-	Bookmark,
-	EllipsisVertical,
-	Heart,
-	MessageCircle,
-	Share2,
-	SquarePen,
-	Trash2,
+  Bookmark,
+  EllipsisVertical,
+  Heart,
+  MessageCircle,
+  Share2,
+  SquarePen,
+  Trash2,
 } from "lucide-react";
 import Link from "next/link";
-import React, { useState } from "react";
+import React, { useEffect, useRef, useState } from "react";
 import { useForm } from "react-hook-form";
 import { z } from "zod";
 import Image from "next/image";
 import {
-	useInnovationsFetchOneQuery,
-	useInnovationsCommentsCreateMutation,
-	useInnovationsCommentsListQuery,
-	useInnovationsCommentsDeleteMutation,
-	useInnovationsCommentsUpdatePatchMutation,
-	useInnovationsCommentsUpdatePutMutation,
-	useInnovationsCommentsReadQuery,
+  useInnovationsFetchOneQuery,
+  useInnovationsCommentsCreateMutation,
+  useInnovationsCommentsListQuery,
+  useInnovationsCommentsDeleteMutation,
+  useInnovationsCommentsUpdatePatchMutation,
+  useInnovationsCommentsUpdatePutMutation,
+  useInnovationsCommentsReadQuery,
 } from "@/redux/features/innovations/innovationsApiSlice";
 import { get_fallback_name } from "@/lib/utils";
 import {
-	useBookmarkInnovation,
-	useLikeInnovation,
-	useUnbookmarkInnovation,
-	useUnlikeInnovation,
+  useBookmarkInnovation,
+  useLikeInnovation,
+  useUnbookmarkInnovation,
+  useUnlikeInnovation,
 } from "@/lib/hooks";
 import { PaginationDemo } from "@/components/Pagination";
+import { embedDashboard } from "@superset-ui/embedded-sdk";
+import axios from 'axios';
 
 type InnovationDetailPageProps = {
-	params: {
-		id: string;
-	};
+  params: {
+    id: string;
+  };
 };
 
 const CommentSchema = z.object({
-	message: z.string().min(2).max(255),
+  message: z.string().min(2).max(255),
 });
 
 type TComment = z.infer<typeof CommentSchema>;
@@ -66,269 +68,383 @@ type TComment = z.infer<typeof CommentSchema>;
 const commentsPerPage = 5;
 
 const InnovationDetailPage = ({ params }: InnovationDetailPageProps) => {
-	const { id } = params;
-	const handleLike = useLikeInnovation(id);
-	const handleUnlike = useUnlikeInnovation(id);
-	const handleBookmark = useBookmarkInnovation(id);
-	const handleUnbookmark = useUnbookmarkInnovation(id);
+  const { id } = params;
+  const handleLike = useLikeInnovation(id);
+  const handleUnlike = useUnlikeInnovation(id);
+  const handleBookmark = useBookmarkInnovation(id);
+  const handleUnbookmark = useUnbookmarkInnovation(id);
 
-	const form = useForm<TComment>({
-		resolver: zodResolver(CommentSchema),
-	});
+  const form = useForm<TComment>({
+    resolver: zodResolver(CommentSchema),
+  });
 
-	const [currentPage, setCurrentPage] = useState(1);
-	// Fetch innovation data
-	const {
-		data: innovation,
-		isLoading: isGettingInnovation,
-		error: errorGettingInnovation,
-	} = useInnovationsFetchOneQuery(id);
-	const [createComment, { isLoading: isCreatingComment }] =
-		useInnovationsCommentsCreateMutation();
-	const {
-		data: commentData,
-		isLoading: isGettingComment,
-		error: errorGettingComments,
-	} = useInnovationsCommentsListQuery({ id: id, page: currentPage });
-	console.log(commentData);
-	// extracting comments  from the request
-	const {
-		results: comments,
-		next: nextCommentPage,
-		previous: previousCommentPage,
-		count: totalComments,
-	} = commentData || {};
+  const [currentPage, setCurrentPage] = useState(1);
+  // Fetch innovation data
+  const {
+    data: innovation,
+    isLoading: isGettingInnovation,
+    error: errorGettingInnovation,
+  } = useInnovationsFetchOneQuery(id);
+  const [createComment, { isLoading: isCreatingComment }] =
+    useInnovationsCommentsCreateMutation();
+  const {
+    data: commentData,
+    isLoading: isGettingComment,
+    error: errorGettingComments,
+  } = useInnovationsCommentsListQuery({ id: id, page: currentPage });
+  console.log(commentData);
+  // extracting comments  from the request
+  const {
+    results: comments,
+    next: nextCommentPage,
+    previous: previousCommentPage,
+    count: totalComments,
+  } = commentData || {};
 
-	// * handling pagination
-	const totalPages =
-		totalComments && Math.ceil(totalComments / commentsPerPage);
-	const handlePrevious = () => {
-		if (currentPage > 1) {
-			setCurrentPage(currentPage - 1);
-		}
-	};
+  // * handling pagination
+  const totalPages =
+    totalComments && Math.ceil(totalComments / commentsPerPage);
+  const handlePrevious = () => {
+    if (currentPage > 1) {
+      setCurrentPage(currentPage - 1);
+    }
+  };
 
-	const handleNext = () => {
-		if (totalPages && currentPage < totalPages) {
-			setCurrentPage(currentPage + 1);
-		}
-	};
-	//initialize toast
-	const { toast } = useToast();
-	//Function that handles submision of validated data
-	const onSubmit = async (data: TComment) => {
-		// useInnovationsCommentsDeleteMutation
-		// useInnovationsCommentsUpdatePatchMutation
-		// useInnovationsCommentsUpdatePutMutation
-		// useInnovationsCommentsReadQuery
+  const handleNext = () => {
+    if (totalPages && currentPage < totalPages) {
+      setCurrentPage(currentPage + 1);
+    }
+  };
+  //initialize toast
+  const { toast } = useToast();
+  //Function that handles submision of validated data
+  const onSubmit = async (data: TComment) => {
+    // useInnovationsCommentsDeleteMutation
+    // useInnovationsCommentsUpdatePatchMutation
+    // useInnovationsCommentsUpdatePutMutation
+    // useInnovationsCommentsReadQuery
 
-		// Submit the data to your API or perform any other action
-		createComment({ id, ...data })
-			.unwrap()
-			.then((response) => {
-				// toast created successfully
-				toast({
-					title: "Comments submitted successfully",
-				});
-				console.log("Response: ", response);
-				form.reset({ message: "" });
-			})
-			.catch((error) => {
-				console.log(error);
-			});
-	};
+    // Submit the data to your API or perform any other action
+    createComment({ id, ...data })
+      .unwrap()
+      .then((response) => {
+        // toast created successfully
+        toast({
+          title: "Comments submitted successfully",
+        });
+        console.log("Response: ", response);
+        form.reset({ message: "" });
+      })
+      .catch((error) => {
+        console.log(error);
+      });
+  };
 
-	return isGettingInnovation || isGettingComment ? (
-		<div>Loading...</div>
-	) : errorGettingInnovation || errorGettingComments ? (
-		<div>Something went wrong</div>
-	) : (
-		<main>
-			<section className="flex flex-col">
-				<div className="flex justify-between items-center p-4">
-					<h2 className="font-semibold text-3xl">{innovation?.title}</h2>
-					<DropdownMenu>
-						<DropdownMenuTrigger asChild>
-							<div className="hover:bg-accent rounded-full p-1">
-								<EllipsisVertical />
-							</div>
-						</DropdownMenuTrigger>
-						<DropdownMenuContent className="w-56">
-							<DropdownMenuItem>
-								<SquarePen className="mr-2 h-4 w-4" />
-								{/* TODO: URL generator */}
-								<Link href={`/dashboard/innovation/edit/${id}`}>
-									<span>Edit</span>
-								</Link>
-							</DropdownMenuItem>
-							<DropdownMenuItem className="hover:bg-destructive active:bg-destructive focus:bg-destructive hover:text-white active:text-white focus:text-white">
-								<Trash2 className="mr-2 h-4 w-4" />
-								<span>Delete</span>
-							</DropdownMenuItem>
-						</DropdownMenuContent>
-					</DropdownMenu>
-				</div>
 
-				<p className="px-4 ">{innovation?.description}</p>
-				<div className="flex items-center justify-between mt-5 px-4 ">
-					<div className="flex items-center gap-3">
-						<Avatar className="h-12 w-12">
-							<AvatarImage src={innovation?.author.profile_picture} />
-							<AvatarFallback className="p-2">
-								{get_fallback_name(
-									innovation?.author.first_name,
-									innovation?.author.last_name
-								)}
-							</AvatarFallback>
-						</Avatar>
-						<div>
-							<p>{`${innovation?.author.first_name} ${innovation?.author.last_name}`}</p>
-							<p className="text-sm">{innovation?.author.email}</p>
-						</div>
-					</div>
+  const supersetUrl = "http://localhost:8088";
+  const supersetApiUrl = supersetUrl + "/api/v1/security";
+  const dashboardId = "795981b3-a645-425b-a9ea-fe8970bc30dd";
+  let supersetData: { access_token: string, refresh_token: string };
 
-					<div className="flex gap-2 md:gap-4">
-						{innovation?.dashboard_link && (
-							<Link href={innovation?.dashboard_link || ""}>
-								<Button className="rounded-full md:px-9"> Visit </Button>
-							</Link>
-						)}
-						{innovation?.dashboard_definitions && (
-							<Link download href={innovation.dashboard_definitions}>
-								<Button className="rounded-full" variant={"outline"}>
-									Download Datasets
-								</Button>
-							</Link>
-						)}
-					</div>
-				</div>
-				<div className="flex p-4 my-2 justify-between bg-accent">
-					<div className="flex gap-3">
-						<span
-							className="flex"
-							onClick={innovation?.is_liked ? handleUnlike : handleLike}
-						>
-							{innovation?.is_liked ? (
-								<Heart className="fill-red-500" />
-							) : (
-								<Heart className="hover:fill-red-500" />
-							)}{" "}
-							{innovation?.likes_number}
-						</span>
-						<span className="flex">
-							<MessageCircle /> {innovation?.comments_number}{" "}
-						</span>
-					</div>
-					<span
-						className="flex"
-						onClick={
-							innovation?.is_bookmarked ? handleUnbookmark : handleBookmark
-						}
-					>
-						{innovation?.is_bookmarked ? (
-							<Bookmark className="fill-green-600" />
-						) : (
-							<Bookmark />
-						)}
-					</span>
-				</div>
-			</section>
-			<section>
-				{innovation?.dashboard_image ? (
-					<Image
-						alt="Innovation Image"
-						width={500}
-						height={600}
-						src={innovation?.dashboard_image}
-					/>
-				) : (
-					<></>
-				)}
-			</section>
+  const dashboardRef = useRef(null);
+  async function fetchGuestTokenFromBackend() {
+    const access_token = await getToken()
+    // Calling guest token
+    const guest_token_body = {
+      resources: [
+        {
+          type: "dashboard",
+          id: dashboardId,
+        },
+      ],
+      rls: [],
+      user: {
+        username: "guest",
+        first_name: "Guest",
+        last_name: "User",
+      },
+    };
 
-			<section className="px-6 pb-4">
-				<Form {...form}>
-					<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
-						<FormField
-							control={form.control}
-							name="message"
-							render={({ field }) => (
-								<FormItem>
-									<FormLabel>Comment</FormLabel>
-									<FormControl>
-										<Textarea placeholder="Type comment here..." {...field} />
-									</FormControl>
-									<FormMessage />
-								</FormItem>
-							)}
-						/>
-						<Button
-							className="rounded-full"
-							type="submit"
-							size={"lg"}
-							disabled={isCreatingComment}
-						>
-							Submit
-						</Button>
-					</form>
-				</Form>
-			</section>
-			{/* Comments container */}
-			<section className="p-7 space-y-4">
-				{comments?.map((comment, index) => (
-					<div className="border p-3 rounded-lg shadow-md" key={index}>
-						<div className="flex items-center justify-between">
-							<div className="flex items-center gap-3">
-								<Avatar className="h-12 w-12">
-									<AvatarImage src={comment.author.profile_picture} />
-									<AvatarFallback className="p-2">
-										{get_fallback_name(
-											innovation?.author.first_name,
-											innovation?.author.last_name
-										)}
-									</AvatarFallback>
-								</Avatar>
-								<div>
-									<p>
-										{comment.author.first_name} {comment.author.last_name}
-									</p>
-									<p className="text-sm">{comment.author.email}</p>
-								</div>
-							</div>
-							<DropdownMenu>
-								<DropdownMenuTrigger asChild>
-									<div className="hover:bg-accent rounded-full p-1">
-										<EllipsisVertical />
-									</div>
-								</DropdownMenuTrigger>
-								<DropdownMenuContent className="w-56">
-									{/* <DropdownMenuItem>
+    const guest_token_headers = {
+      headers: {
+        "Content-Type": "application/json",
+        Authorization: "Bearer " + access_token,
+      },
+    }; console.log("Access token ", access_token)
+
+    console.log(supersetApiUrl + '/guest_token/')
+    console.log(guest_token_body)
+    console.log(guest_token_headers)
+    return await axios.post(supersetApiUrl + '/guest_token/', guest_token_body, guest_token_headers)
+      .then(dt => {
+        console.log("guestToken: ", dt.data['token'])
+        return dt.data['token']
+      })
+      .catch(error => console.log(error))
+  }
+
+
+  async function getToken() {
+    //calling login to get access token
+    const login_body = {
+      password: "1",
+      provider: "db",
+      refresh: true,
+      username: "guest",
+    };
+
+    const login_headers = {
+      headers: {
+        "Content-Type": "application/json",
+      },
+    };
+
+    console.log(supersetApiUrl + '/login')
+    const { data } = await axios.post(supersetApiUrl + '/login', login_body, login_headers)
+    const access_token = data['access_token']
+    return access_token
+
+  }
+
+
+  // console.log("ref: ", dashboardRef.current)
+  // if (dashboardRef.current !== null) {
+  //   console.log("embeding")
+  //   embed()
+  // } else {
+  //   console.log("Not embeding")
+  // }
+  useEffect(() => {
+    const embed = async () => {
+      embedDashboard({
+        id: dashboardId,  // given by the Superset embedding UI
+        supersetDomain: supersetUrl,
+        mountPoint: document.getElementById("superset-container"), // html element in which iframe render
+        fetchGuestToken: () => fetchGuestTokenFromBackend(),
+        dashboardUiConfig: {
+          hideTitle: false,
+          hideChartControls: true,
+          hideTab: true,
+          filters: {
+            expanded: true,
+          },
+        }
+      });
+    }
+    console.log("ref: ", dashboardRef.current)
+    if (dashboardRef.current !== null) {
+      console.log("embeding")
+      embed()
+
+      const iframe = document.querySelector("iframe")
+      console.log(iframe);
+
+      if (iframe) {
+        iframe.style.width = '100%'; // Set the width as needed
+        iframe.style.minHeight = '70vw'; // Set the height as needed
+        iframe.style.overflow = 'hidden'
+        iframe.style.border = "0"
+      }
+    } else {
+      console.log("Not embeding")
+    }
+  }, [fetchGuestTokenFromBackend, getToken])
+
+  return isGettingInnovation || isGettingComment ? (
+    <div>Loading...</div>
+  ) : errorGettingInnovation || errorGettingComments ? (
+    <div>Something went wrong</div>
+  ) : (
+    <main>
+      <section className="flex flex-col">
+        <div className="flex justify-between items-center p-4">
+          <h2 className="font-semibold text-3xl">{innovation?.title}</h2>
+          <DropdownMenu>
+            <DropdownMenuTrigger asChild>
+              <div className="hover:bg-accent rounded-full p-1">
+                <EllipsisVertical />
+              </div>
+            </DropdownMenuTrigger>
+            <DropdownMenuContent className="w-56">
+              <DropdownMenuItem>
+                <SquarePen className="mr-2 h-4 w-4" />
+                {/* TODO: URL generator */}
+                <Link href={`/dashboard/innovation/edit/${id}`}>
+                  <span>Edit</span>
+                </Link>
+              </DropdownMenuItem>
+              <DropdownMenuItem className="hover:bg-destructive active:bg-destructive focus:bg-destructive hover:text-white active:text-white focus:text-white">
+                <Trash2 className="mr-2 h-4 w-4" />
+                <span>Delete</span>
+              </DropdownMenuItem>
+            </DropdownMenuContent>
+          </DropdownMenu>
+        </div>
+
+        <p className="px-4 ">{innovation?.description}</p>
+        <div className="flex items-center justify-between mt-5 px-4 ">
+          <div className="flex items-center gap-3">
+            <Avatar className="h-12 w-12">
+              <AvatarImage src={innovation?.author.profile_picture} />
+              <AvatarFallback className="p-2">
+                {get_fallback_name(
+                  innovation?.author.first_name,
+                  innovation?.author.last_name
+                )}
+              </AvatarFallback>
+            </Avatar>
+            <div>
+              <p>{`${innovation?.author.first_name} ${innovation?.author.last_name}`}</p>
+              <p className="text-sm">{innovation?.author.email}</p>
+            </div>
+          </div>
+
+          <div className="flex gap-2 md:gap-4">
+            {innovation?.dashboard_link && (
+              <Link href={innovation?.dashboard_link || ""}>
+                <Button className="rounded-full md:px-9"> Visit </Button>
+              </Link>
+            )}
+            {innovation?.dashboard_definitions && (
+              <Link download href={innovation.dashboard_definitions}>
+                <Button className="rounded-full" variant={"outline"}>
+                  Download Datasets
+                </Button>
+              </Link>
+            )}
+          </div>
+        </div>
+        <div className="flex p-4 my-2 justify-between bg-accent">
+          <div className="flex gap-3">
+            <span
+              className="flex"
+              onClick={innovation?.is_liked ? handleUnlike : handleLike}
+            >
+              {innovation?.is_liked ? (
+                <Heart className="fill-red-500" />
+              ) : (
+                <Heart className="hover:fill-red-500" />
+              )}{" "}
+              {innovation?.likes_number}
+            </span>
+            <span className="flex">
+              <MessageCircle /> {innovation?.comments_number}{" "}
+            </span>
+          </div>
+          <span
+            className="flex"
+            onClick={
+              innovation?.is_bookmarked ? handleUnbookmark : handleBookmark
+            }
+          >
+            {innovation?.is_bookmarked ? (
+              <Bookmark className="fill-green-600" />
+            ) : (
+              <Bookmark />
+            )}
+          </span>
+        </div>
+      </section>
+      <section>
+        {/* TODO: Dashboard display */}
+        <div id="superset-container" ref={dashboardRef} className="w-full">
+        </div>
+
+        {innovation?.dashboard_image ? (
+          <Image
+            alt="Innovation Image"
+            width={500}
+            height={600}
+            src={innovation?.dashboard_image}
+          />
+        ) : (
+          <></>
+        )}
+      </section>
+
+      <section className="px-6 pb-4">
+        <Form {...form}>
+          <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
+            <FormField
+              control={form.control}
+              name="message"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>Comment</FormLabel>
+                  <FormControl>
+                    <Textarea placeholder="Type comment here..." {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+            <Button
+              className="rounded-full"
+              type="submit"
+              size={"lg"}
+              disabled={isCreatingComment}
+            >
+              Submit
+            </Button>
+          </form>
+        </Form>
+      </section>
+      {/* Comments container */}
+      <section className="p-7 space-y-4">
+        {comments?.map((comment, index) => (
+          <div className="border p-3 rounded-lg shadow-md" key={index}>
+            <div className="flex items-center justify-between">
+              <div className="flex items-center gap-3">
+                <Avatar className="h-12 w-12">
+                  <AvatarImage src={comment.author.profile_picture} />
+                  <AvatarFallback className="p-2">
+                    {get_fallback_name(
+                      innovation?.author.first_name,
+                      innovation?.author.last_name
+                    )}
+                  </AvatarFallback>
+                </Avatar>
+                <div>
+                  <p>
+                    {comment.author.first_name} {comment.author.last_name}
+                  </p>
+                  <p className="text-sm">{comment.author.email}</p>
+                </div>
+              </div>
+              <DropdownMenu>
+                <DropdownMenuTrigger asChild>
+                  <div className="hover:bg-accent rounded-full p-1">
+                    <EllipsisVertical />
+                  </div>
+                </DropdownMenuTrigger>
+                <DropdownMenuContent className="w-56">
+                  {/* <DropdownMenuItem>
 										<SquarePen className="mr-2 h-4 w-4" />
 										// TODO: Comment Editing
 										<Link href={""}>
 											<span>Edit</span>
 										</Link>
 									</DropdownMenuItem> */}
-									<DropdownMenuItem className="hover:bg-destructive active:bg-destructive focus:bg-destructive hover:text-white active:text-white focus:text-white">
-										<Trash2 className="mr-2 h-4 w-4" />
-										<span>Delete</span>
-									</DropdownMenuItem>
-								</DropdownMenuContent>
-							</DropdownMenu>
-						</div>
-						<Separator className="my-3" />
-						<p>{comment.text}</p>
-					</div>
-				))}
-				<PaginationDemo
-					currentPage={currentPage}
-					totalPages={totalPages ?? 0}
-					onPrevious={handlePrevious}
-					onNext={handleNext}
-				/>
-			</section>
-		</main>
-	);
+                  <DropdownMenuItem className="hover:bg-destructive active:bg-destructive focus:bg-destructive hover:text-white active:text-white focus:text-white">
+                    <Trash2 className="mr-2 h-4 w-4" />
+                    <span>Delete</span>
+                  </DropdownMenuItem>
+                </DropdownMenuContent>
+              </DropdownMenu>
+            </div>
+            <Separator className="my-3" />
+            <p>{comment.text}</p>
+          </div>
+        ))}
+        <PaginationDemo
+          currentPage={currentPage}
+          totalPages={totalPages ?? 0}
+          onPrevious={handlePrevious}
+          onNext={handleNext}
+        />
+      </section>
+    </main>
+  );
 };
 
 export default InnovationDetailPage;
diff --git a/superset-embed b/superset-embed
new file mode 160000
index 0000000..698e9b9
--- /dev/null
+++ b/superset-embed
@@ -0,0 +1 @@
+Subproject commit 698e9b95593ec7b6a648ef79965c54d39f746c6f

From 8d89210876f3f2e77c7a74522054ceef04a3478a Mon Sep 17 00:00:00 2001
From: Karume-lab <danielkarume@outlook.com>
Date: Thu, 6 Jun 2024 12:47:23 +0300
Subject: [PATCH 2/2] fix: :adhesive_bandage: remove repo

---
 superset-embed | 1 -
 1 file changed, 1 deletion(-)
 delete mode 160000 superset-embed

diff --git a/superset-embed b/superset-embed
deleted file mode 160000
index 698e9b9..0000000
--- a/superset-embed
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 698e9b95593ec7b6a648ef79965c54d39f746c6f