diff --git a/src/App.tsx b/src/App.tsx index 9ab9d76b7..801024726 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -299,6 +299,8 @@ function App() { { path: "manage-locations", element: } /> }, { path: "manage-locations/add/:item", element: }, { path: "manage-locations/edit/:item", element: }, + { path: "management/manage-locations/add/:item", element: }, + { path: "management/manage-locations/edit/:item", element: }, { path: "hackathon/organizers/:id", element: } /> }, { path: "learningcircle/your-circles", element: }, { path: "learningcircle/dashboard/:id", element: }, diff --git a/src/modules/Dashboard/layouts/DashboardRootLayout.tsx b/src/modules/Dashboard/layouts/DashboardRootLayout.tsx index c33588590..565ab1adb 100644 --- a/src/modules/Dashboard/layouts/DashboardRootLayout.tsx +++ b/src/modules/Dashboard/layouts/DashboardRootLayout.tsx @@ -2,32 +2,16 @@ import styles from "../components/SideNavBar.module.css"; import { Outlet, useNavigate } from "react-router-dom"; import SideNavBar from "../components/SideNavBar"; import TopNavBar from "../components/TopNavBar"; -import { AlertBanner } from "../components/AlertBanner"; -import React, { Suspense, useEffect, useCallback, useState } from "react"; +import React, { Suspense, useEffect, useState } from "react"; import { FaRocket, FaUser, FaUserFriends } from "react-icons/fa"; import { FaMagnifyingGlass, FaMapLocationDot, FaHouse, FaRankingStar } from "react-icons/fa6"; import { IoGlobeOutline } from "react-icons/io5"; -import { FiRefreshCw } from "react-icons/fi"; import { roles, managementTypes } from "@/MuLearnServices/types"; import MuLoader from "@/MuLearnComponents/MuLoader/MuLoader"; import { dashboardRoutes, qseverseRoutes } from "@/MuLearnServices/urls"; import { privateGateway, publicGateway } from "@/MuLearnServices/apiGateways"; import { UserProfile, useUserStore, useQseverseStore } from "/src/ZustandProvider"; import { sendRefreshToken } from "@/modules/utils/cdr"; -import { - Modal, - ModalOverlay, - ModalContent, - ModalHeader, - ModalFooter, - ModalBody, - ModalCloseButton, - Button, - VStack, - Text, - useDisclosure, -} from "@chakra-ui/react"; -import toast from "react-hot-toast"; interface CrateType { navigate: (channelId: string) => void; @@ -252,45 +236,7 @@ const DashboardRootLayout = (props: { component?: any }) => { // } ]; - // Modal for connect wallet - const { isOpen: isConnectModalOpen, onOpen: onConnectModalOpen, onClose: onConnectModalClose } = useDisclosure(); - const [isRefreshingConnection, setIsRefreshingConnection] = useState(false); - // Handler for QSeverse connect action - opens modal - const handleConnectQseverse = useCallback(() => { - onConnectModalOpen(); - }, [onConnectModalOpen]); - - // Handler for refreshing connection status - const handleRefreshConnection = useCallback(async () => { - if (!userInfo.muid) { - toast.error("Unable to check connection - user info not available"); - return; - } - - setIsRefreshingConnection(true); - try { - const response = await publicGateway.get(qseverseRoutes.getConnectedUsers, { - params: { key: 'muid', value: userInfo.muid } - }); - const dids = response?.data?.response?.dids; - if (dids && Array.isArray(dids) && dids.length > 0) { - setQseverseStatus('connected'); - toast.success("Wallet connected successfully!"); - onConnectModalClose(); - } else { - toast.error("No connected wallet found. Please link your wallet in the QSeverse app first."); - } - } catch (error) { - console.error("Error refreshing connection:", error); - toast.error("Failed to check connection status."); - } finally { - setIsRefreshingConnection(false); - } - }, [userInfo.muid, setQseverseStatus, onConnectModalClose]); - - const refreshToken = localStorage.getItem("refreshToken"); - const showQseverseBanner = refreshToken && qseverseStatus === 'not_connected'; if (isLoading) { return
@@ -309,83 +255,7 @@ const DashboardRootLayout = (props: { component?: any }) => {
- {showQseverseBanner && ( -
- } - className="floating-pill" - /> -
- )} - - {/* Connect Wallet Modal */} - - - - Connect your QSeverse Wallet - - - - - To claim verifiable credentials for your achievements, you need to link your QSeverse wallet. - - - Steps to connect: - - - Download the QSeverse app from your app store and sign up - Connect your MuLearn account - Your wallet will be automatically linked - Click "Refresh Status" below to verify - - - - - - - - - - ); }; diff --git a/src/modules/Dashboard/modules/Profile/pages/Profile.tsx b/src/modules/Dashboard/modules/Profile/pages/Profile.tsx index 1ced9465b..7e218dc51 100644 --- a/src/modules/Dashboard/modules/Profile/pages/Profile.tsx +++ b/src/modules/Dashboard/modules/Profile/pages/Profile.tsx @@ -1,5 +1,5 @@ import moment from "moment"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState, useCallback } from "react"; import dpm from "../assets/images/dpm.webp"; import Karma, { KarmaWhite } from "../assets/svg/Karma"; import MulearnBrand from "../assets/svg/MulearnBrand"; @@ -35,9 +35,9 @@ import Socials from "../components/Socials/pages/Socials"; import ShareProfilePopUp from "../components/ShareProfilePopUp/pages/ShareProfilePopUp"; import HelmetMetaTags from "../components/HelmetMetaTags/HelmetMetaTags"; import { isDev } from "@/MuLearnServices/common_functions"; -import { Img, SimpleGrid, Switch } from "@chakra-ui/react"; +import { Img, SimpleGrid, Switch, Modal, ModalOverlay, ModalContent, ModalHeader, ModalFooter, ModalBody, ModalCloseButton, Button, VStack, Text, useDisclosure } from "@chakra-ui/react"; import AchievementCard from "../components/Achievements/AchievementCard"; -import { useUserStore } from "/src/ZustandProvider"; +import { useUserStore, useQseverseStore } from "/src/ZustandProvider"; import { getAchievements } from "../../ManageAchievements/services/api"; import { AchievementData } from "../../ManageAchievements/ManageAchievementsInterface"; import AchievementCardOne from "../components/Achievements/AchievementCardOne"; @@ -47,6 +47,10 @@ import EditCollegePopUp from "../components/EditProfilePopUp/pages/EditCollegePo import { useMuShepherdTour } from "../../../../../components/MuComponents/MuTour/MuShepherdTour"; import MuShepherdTourButton from "../../../../../components/MuComponents/MuTour/MuShepherdTourButton"; import { profileShepherdTourSteps } from "../../../../../components/MuComponents/MuTour/profileShepherdTourSteps"; +import { FiRefreshCw } from "react-icons/fi"; +import { AlertBanner } from "../../../components/AlertBanner"; +import { qseverseRoutes } from "@/MuLearnServices/urls"; +import { publicGateway } from "@/MuLearnServices/apiGateways"; @@ -144,6 +148,53 @@ const Profile = () => { const [userPreferences, setUserPreferences] = useState(null); const [preferencesLoading, setPreferencesLoading] = useState(false); + // QWallet Modal state and handlers + const { + connectionStatus: qseverseStatus, + hasCheckedConnection: hasCheckedQseverse, + setConnectionStatus: setQseverseStatus, + setHasCheckedConnection: setHasCheckedQseverse + } = useQseverseStore(); + const { isOpen: isConnectModalOpen, onOpen: onConnectModalOpen, onClose: onConnectModalClose } = useDisclosure(); + const [isRefreshingConnection, setIsRefreshingConnection] = useState(false); + const { userInfo } = useUserStore(); + + // Handler for QSeverse connect action - opens modal + const handleConnectQseverse = useCallback(() => { + onConnectModalOpen(); + }, [onConnectModalOpen]); + + // Handler for refreshing connection status + const handleRefreshConnection = useCallback(async () => { + if (!userInfo.muid) { + toast.error("Unable to check connection - user info not available"); + return; + } + + setIsRefreshingConnection(true); + try { + const response = await publicGateway.get(qseverseRoutes.getConnectedUsers, { + params: { key: 'muid', value: userInfo.muid } + }); + const dids = response?.data?.response?.dids; + if (dids && Array.isArray(dids) && dids.length > 0) { + setQseverseStatus('connected'); + toast.success("Wallet connected successfully!"); + onConnectModalClose(); + } else { + toast.error("No connected wallet found. Please link your wallet in the QSeverse app first."); + } + } catch (error) { + console.error("Error refreshing connection:", error); + toast.error("Failed to check connection status."); + } finally { + setIsRefreshingConnection(false); + } + }, [userInfo.muid, setQseverseStatus, onConnectModalClose]); + + const refreshToken = localStorage.getItem("refreshToken"); + const showQseverseBanner = refreshToken && qseverseStatus === 'not_connected' && !id; + // Initialize Profile Tour - using Shepherd.js for better scroll handling const tour = useMuShepherdTour({ steps: profileShepherdTourSteps, @@ -1018,6 +1069,83 @@ const Profile = () => { ) )} + + {showQseverseBanner && ( +
+ } + className="floating-pill" + /> +
+ )} + + {/* Connect Wallet Modal */} + + + + Connect your QSeverse Wallet + + + + + To claim verifiable credentials for your achievements, you need to link your QSeverse wallet. + + + Steps to connect: + + + Download the QSeverse app from your app store and sign up + Connect your MuLearn account + Your wallet will be automatically linked + Click "Refresh Status" below to verify + + + + + + + + + + ); };