diff --git a/src/app/[orgId]/MemberResourcesPortal.tsx b/src/app/[orgId]/MemberResourcesPortal.tsx
index 142d5516..ad412b1e 100644
--- a/src/app/[orgId]/MemberResourcesPortal.tsx
+++ b/src/app/[orgId]/MemberResourcesPortal.tsx
@@ -4,21 +4,42 @@ import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
-import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
-import { ExternalLink, Globe, ShieldCheck, Search, RefreshCw, AlertCircle, Plus, Shield, ShieldOff, ChevronLeft, ChevronRight, Building2, Key, KeyRound, Fingerprint, AtSign, Copy, InfoIcon } from "lucide-react";
import {
- Tooltip,
- TooltipContent,
- TooltipProvider,
- TooltipTrigger,
-} from "@/components/ui/tooltip";
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue
+} from "@/components/ui/select";
+import {
+ ExternalLink,
+ Globe,
+ Search,
+ RefreshCw,
+ AlertCircle,
+ ChevronLeft,
+ ChevronRight,
+ Key,
+ KeyRound,
+ Fingerprint,
+ AtSign,
+ Copy,
+ InfoIcon,
+ Combine
+} from "lucide-react";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { GetUserResourcesResponse } from "@server/routers/resource/getUserResources";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { useToast } from "@app/hooks/useToast";
+import { InfoPopup } from "@/components/ui/info-popup";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger
+} from "@/components/ui/tooltip";
// Update Resource type to include site information
type Resource = {
@@ -42,26 +63,34 @@ type MemberResourcesPortalProps = {
};
// Favicon component with fallback
-const ResourceFavicon = ({ domain, enabled }: { domain: string; enabled: boolean }) => {
+const ResourceFavicon = ({
+ domain,
+ enabled
+}: {
+ domain: string;
+ enabled: boolean;
+}) => {
const [faviconError, setFaviconError] = useState(false);
const [faviconLoaded, setFaviconLoaded] = useState(false);
-
+
// Extract domain for favicon URL
- const cleanDomain = domain.replace(/^https?:\/\//, '').split('/')[0];
+ const cleanDomain = domain.replace(/^https?:\/\//, "").split("/")[0];
const faviconUrl = `https://www.google.com/s2/favicons?domain=${cleanDomain}&sz=32`;
-
+
const handleFaviconLoad = () => {
setFaviconLoaded(true);
setFaviconError(false);
};
-
+
const handleFaviconError = () => {
setFaviconError(true);
setFaviconLoaded(false);
};
if (faviconError || !enabled) {
- return ;
+ return (
+
+ );
}
return (
@@ -72,7 +101,7 @@ const ResourceFavicon = ({ domain, enabled }: { domain: string; enabled: boolean
@@ -80,198 +109,107 @@ const ResourceFavicon = ({ domain, enabled }: { domain: string; enabled: boolean
);
};
-// Enhanced status badge component
-const StatusBadge = ({ enabled, protected: isProtected, resource }: { enabled: boolean; protected: boolean; resource: Resource }) => {
- if (!enabled) {
- return (
-
-
-
-
-
-
- Resource Disabled
-
-
-
- );
- }
-
- if (isProtected) {
- return (
-
-
-
-
-
-
-
-
- Protected Resource
-
-
Authentication Methods:
-
- {resource.sso && (
-
-
-
-
-
Single Sign-On (SSO)
-
- )}
- {resource.password && (
-
-
-
-
-
Password Protected
-
- )}
- {resource.pincode && (
-
- )}
- {resource.whitelist && (
-
- )}
-
-
-
-
-
- );
- }
-
- return (
-
-
-
- );
-};
-
// Resource Info component
const ResourceInfo = ({ resource }: { resource: Resource }) => {
- const hasAuthMethods = resource.sso || resource.password || resource.pincode || resource.whitelist;
-
- return (
-
-
-
-
-
+ const hasAuthMethods =
+ resource.sso ||
+ resource.password ||
+ resource.pincode ||
+ resource.whitelist;
+
+ const infoContent = (
+
+ {/* Site Information */}
+ {resource.siteName && (
+
+
Site
+
+
+ {resource.siteName}
-
-
- {/* Site Information */}
- {resource.siteName && (
-
-
Site
-
-
- {resource.siteName}
-
-
- )}
+
+ )}
- {/* Authentication Methods */}
- {hasAuthMethods && (
-
-
Authentication Methods
-
- {resource.sso && (
-
-
-
-
-
Single Sign-On (SSO)
-
- )}
- {resource.password && (
-
-
-
-
-
Password Protected
-
- )}
- {resource.pincode && (
-
- )}
- {resource.whitelist && (
-
- )}
-
-
- )}
-
- {/* Resource Status - if disabled */}
- {!resource.enabled && (
-
- )}
-
-
-
- );
-};
-
-// Site badge component
-const SiteBadge = ({ resource }: { resource: Resource }) => {
- if (!resource.siteName) {
- return null;
- }
-
- return (
-
-
-
-
-
+ {/* Authentication Methods */}
+ {hasAuthMethods && (
+
+
+ Authentication Methods
-
-
- {resource.siteName}
-
-
-
+
+ {resource.sso && (
+
+
+
+
+
+ Single Sign-On (SSO)
+
+
+ )}
+ {resource.password && (
+
+
+
+
+
+ Password Protected
+
+
+ )}
+ {resource.pincode && (
+
+ )}
+ {resource.whitelist && (
+
+ )}
+
+
+ )}
+
+ {/* Resource Status - if disabled */}
+ {!resource.enabled && (
+
+
+
+
+ Resource Disabled
+
+
+
+ )}
+
);
+
+ return {infoContent};
};
// Pagination component
-const PaginationControls = ({
- currentPage,
- totalPages,
+const PaginationControls = ({
+ currentPage,
+ totalPages,
onPageChange,
totalItems,
- itemsPerPage
-}: {
- currentPage: number;
- totalPages: number;
+ itemsPerPage
+}: {
+ currentPage: number;
+ totalPages: number;
onPageChange: (page: number) => void;
totalItems: number;
itemsPerPage: number;
@@ -286,7 +224,7 @@ const PaginationControls = ({
Showing {startItem}-{endItem} of {totalItems} resources
-
+
Previous
-
+
- {Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => {
- // Show first page, last page, current page, and 2 pages around current
- const showPage =
- page === 1 ||
- page === totalPages ||
- Math.abs(page - currentPage) <= 1;
-
- const showEllipsis =
- (page === 2 && currentPage > 4) ||
- (page === totalPages - 1 && currentPage < totalPages - 3);
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map(
+ (page) => {
+ // Show first page, last page, current page, and 2 pages around current
+ const showPage =
+ page === 1 ||
+ page === totalPages ||
+ Math.abs(page - currentPage) <= 1;
- if (!showPage && !showEllipsis) return null;
+ const showEllipsis =
+ (page === 2 && currentPage > 4) ||
+ (page === totalPages - 1 &&
+ currentPage < totalPages - 3);
+
+ if (!showPage && !showEllipsis) return null;
+
+ if (showEllipsis) {
+ return (
+
+ ...
+
+ );
+ }
- if (showEllipsis) {
return (
-
- ...
-
+
);
}
-
- return (
-
- );
- })}
+ )}
-
+