diff --git a/Channel-Backend/src/services/auth.service.ts b/Channel-Backend/src/services/auth.service.ts index 5ebbe8b..4c0f201 100644 --- a/Channel-Backend/src/services/auth.service.ts +++ b/Channel-Backend/src/services/auth.service.ts @@ -441,6 +441,7 @@ export class AuthService { mfaEnabled: true, organizationId: true, onboardingStatus: true, + partnerGroup: true, createdAt: true, updatedAt: true, assignedNdaId: true, @@ -472,6 +473,7 @@ export class AuthService { mfaEnabled: true, organizationId: true, onboardingStatus: true, + partnerGroup: true, createdAt: true, updatedAt: true, assignedNdaId: true, diff --git a/Channel-Frontend/src/pages/AssetsPage.tsx b/Channel-Frontend/src/pages/AssetsPage.tsx index dbcbb29..8946420 100644 --- a/Channel-Frontend/src/pages/AssetsPage.tsx +++ b/Channel-Frontend/src/pages/AssetsPage.tsx @@ -1,7 +1,7 @@ import { useState, useEffect } from "react"; import { motion } from "framer-motion"; import type { Variants } from "framer-motion"; -import { UploadCloud, Search, File, CheckCircle, Share2, Folder } from "lucide-react"; +import { UploadCloud, Search, File, CheckCircle, Share2, Folder, Sparkles } from "lucide-react"; import { useAuthStore } from "../hooks/use-auth"; import { axiosInstance } from "../services/axios"; import { @@ -97,12 +97,13 @@ export const AssetsPage = () => { setAssets(assetsData); setSelectedAssetIds([]); + // Load groups for both ADMIN (for managing) and PARTNER (for recommendations) + const groupsData = await getAssetGroups(); + setGroups(groupsData); + if (user?.role === "ADMIN") { const orgsData = await getOrganizations(); setOrganizations(orgsData); - - const groupsData = await getAssetGroups(); - setGroups(groupsData); } } catch (err) { console.error("Failed to fetch assets data", err); @@ -366,6 +367,24 @@ export const AssetsPage = () => { ); + // Find recommended assets based on user's partnerGroup matching any AssetGroup.name + const recommendedGroup = user?.partnerGroup && user.role === "PARTNER_USER" + ? groups.find(g => g.name.trim().toLowerCase() === user.partnerGroup?.trim().toLowerCase()) + : null; + + // Only recommend assets that the partner actually has permission to access + const recommendedAssets = recommendedGroup + ? recommendedGroup.assets.filter(recAsset => + assets.some(allAsset => allAsset.id === recAsset.id) + ) + : []; + + const showRecommendations = + user?.role === "PARTNER_USER" && + recommendedAssets.length > 0 && + searchQuery === "" && + selectedCategory === "ALL"; + return (
@@ -373,43 +392,101 @@ export const AssetsPage = () => {
- ) : filteredAssets.length === 0 ? ( -
- -

No assets found

-

- There are no assets matching your criteria. -

-
) : ( - - {filteredAssets.map((asset) => ( - - setExpandedAssetId(expandedAssetId === asset.id ? null : asset.id)} - /> + <> + {showRecommendations && ( +
+
+
+
+
+ + Curated for {user?.partnerGroup} +
+

Recommended for You

+

+ Hand-picked digital assets, guides, and templates selected specifically for your partner category. +

+
+
+ + {/* Grid of Recommended Assets */} + + {recommendedAssets.map((asset) => ( + + setExpandedAssetId(expandedAssetId === asset.id ? null : asset.id)} + /> + + ))} + +
+ )} + + {showRecommendations && ( +
+

All Resources

+
+ )} + + {filteredAssets.length === 0 ? ( +
+ +

No assets found

+

+ There are no assets matching your criteria. +

+
+ ) : ( + + {filteredAssets.map((asset) => ( + + setExpandedAssetId(expandedAssetId === asset.id ? null : asset.id)} + /> + + ))} - ))} - + )} + )}
diff --git a/Channel-Frontend/src/types/auth.ts b/Channel-Frontend/src/types/auth.ts index 255e763..76c8f0e 100644 --- a/Channel-Frontend/src/types/auth.ts +++ b/Channel-Frontend/src/types/auth.ts @@ -4,6 +4,7 @@ export interface User { role: 'ADMIN' | 'PARTNER_USER'; organizationId: string | null; onboardingStatus?: string; + partnerGroup?: string | null; } export interface AuthResponse {