diff --git a/src/components/Activity/ActivityStream.tsx b/src/components/Activity/ActivityStream.tsx
index f262093a7..7817d72bb 100644
--- a/src/components/Activity/ActivityStream.tsx
+++ b/src/components/Activity/ActivityStream.tsx
@@ -31,10 +31,15 @@ export type UserStreamActivity = {
type ActivityStreamProps = {
activities: UserStreamActivity[];
className?: string;
+ onResourceClick?: (
+ resourceId: string,
+ resourceType: ResourceType,
+ isCustomResource: boolean,
+ ) => void;
};
export function ActivityStream(props: ActivityStreamProps) {
- const { activities, className } = props;
+ const { activities, className, onResourceClick } = props;
const [showAll, setShowAll] = useState(false);
const [selectedActivity, setSelectedActivity] =
@@ -92,15 +97,25 @@ export function ActivityStream(props: ActivityStreamProps) {
? `/r/${resourceSlug}`
: `/${resourceId}`;
- const resourceLinkComponent = (
-
- {resourceTitle}
-
- );
+ const resourceLinkComponent =
+ onResourceClick && resourceType !== 'question' ? (
+
+ ) : (
+
+ {resourceTitle}
+
+ );
const topicCount = topicTitles?.length || 0;
diff --git a/src/components/Activity/ResourceProgress.tsx b/src/components/Activity/ResourceProgress.tsx
index 4bca95a05..28c88ec9f 100644
--- a/src/components/Activity/ResourceProgress.tsx
+++ b/src/components/Activity/ResourceProgress.tsx
@@ -17,6 +17,7 @@ type ResourceProgressType = {
isCustomResource: boolean;
roadmapSlug?: string;
showActions?: boolean;
+ onResourceClick?: () => void;
};
export function ResourceProgress(props: ResourceProgressType) {
@@ -24,6 +25,7 @@ export function ResourceProgress(props: ResourceProgressType) {
showClearButton = true,
isCustomResource,
showActions = true,
+ onResourceClick,
} = props;
const userId = getUser()?.id;
@@ -53,13 +55,21 @@ export function ResourceProgress(props: ResourceProgressType) {
const totalMarked = doneCount + skippedCount;
const progressPercentage = getPercentage(totalMarked, totalCount);
+ const Slot = onResourceClick ? 'button' : 'a';
+
return (
-
@@ -74,7 +84,7 @@ export function ResourceProgress(props: ResourceProgressType) {
width: `${progressPercentage}%`,
}}
>
-
+
{showActions && (
diff --git a/src/components/TeamActivity/TeamActivityItem.tsx b/src/components/TeamActivity/TeamActivityItem.tsx
index 8138a2c46..f0e287ee6 100644
--- a/src/components/TeamActivity/TeamActivityItem.tsx
+++ b/src/components/TeamActivity/TeamActivityItem.tsx
@@ -4,6 +4,8 @@ import type { TeamStreamActivity } from './TeamActivityPage';
import { ChevronsDown, ChevronsUp } from 'lucide-react';
import { ActivityTopicTitles } from '../Activity/ActivityTopicTitles';
import { cn } from '../../lib/classname';
+import { useStore } from '@nanostores/react';
+import { $currentTeam } from '../../stores/team';
type TeamActivityItemProps = {
onTopicClick?: (activity: TeamStreamActivity) => void;
@@ -22,6 +24,7 @@ export function TeamActivityItem(props: TeamActivityItemProps) {
const { user, onTopicClick, teamId } = props;
const { activities } = user;
+ const currentTeam = useStore($currentTeam);
const [showAll, setShowAll] = useState(false);
const resourceLink = (activity: TeamStreamActivity) => {
@@ -62,10 +65,25 @@ export function TeamActivityItem(props: TeamActivityItemProps) {
? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${user.avatar}`
: '/images/default-avatar.png';
+ const isPersonalProgressOnly =
+ currentTeam?.personalProgressOnly &&
+ currentTeam.role === 'member' &&
+ user.memberId !== currentTeam.memberId;
const username = (
{
+ if (isPersonalProgressOnly) {
+ e.preventDefault();
+ }
+ }}
+ aria-disabled={isPersonalProgressOnly}
>
(null);
@@ -38,6 +43,12 @@ export function TeamMemberDetailsPage() {
useState(null);
const [currPage, setCurrPage] = useState(1);
+ const [selectedResource, setSelectedResource] = useState<{
+ resourceId: string;
+ resourceType: ResourceType;
+ isCustomResource?: boolean;
+ } | null>(null);
+
const loadMemberProgress = async () => {
const { response, error } = await httpGet(
`${import.meta.env.PUBLIC_API_URL}/v1-get-team-member-progresses/${teamId}/${memberId}`,
@@ -90,7 +101,25 @@ export function TeamMemberDetailsPage() {
return (
<>
-
+ {selectedResource && (
+
setSelectedResource(null)}
+ onShowMyProgress={() => {
+ window.location.href = `/team/member?t=${teamId}&m=${currentTeam?.memberId}`;
+ }}
+ />
+ )}
+
{
+ setSelectedResource({
+ resourceId: progress.resourceId,
+ resourceType: progress.resourceType,
+ isCustomResource: progress.isCustomResource,
+ });
+ }}
/>
);
})}
@@ -146,6 +182,9 @@ export function TeamMemberDetailsPage() {
activities={
memberActivity?.data?.flatMap((act) => act.activity) || []
}
+ onResourceClick={(resourceId, resourceType, isCustomResource) => {
+ setSelectedResource({ resourceId, resourceType, isCustomResource });
+ }}
/>
{
+ if (isPersonalProgressOnly) {
+ e.preventDefault();
+ }
+ }}
+ aria-disabled={isPersonalProgressOnly}
>
{member.name}
diff --git a/src/components/TeamProgress/MemberProgressItem.tsx b/src/components/TeamProgress/MemberProgressItem.tsx
index b8b5d0582..b20875999 100644
--- a/src/components/TeamProgress/MemberProgressItem.tsx
+++ b/src/components/TeamProgress/MemberProgressItem.tsx
@@ -1,5 +1,8 @@
+import { useStore } from '@nanostores/react';
import type { TeamMember } from './TeamProgressPage';
import { useState } from 'react';
+import { $currentTeam } from '../../stores/team';
+import { cn } from '../../lib/classname';
type MemberProgressItemProps = {
member: TeamMember;
@@ -18,12 +21,17 @@ export function MemberProgressItem(props: MemberProgressItemProps) {
teamId,
} = props;
+ const currentTeam = useStore($currentTeam);
const memberProgress = member?.progress?.sort((a, b) => {
return b.done - a.done;
});
const [showAll, setShowAll] = useState(false);
+ const isPersonalProgressOnly =
+ currentTeam?.personalProgressOnly &&
+ currentTeam.role === 'member' &&
+ String(member._id) !== currentTeam.memberId;
const memberDetailsUrl = `/team/member?t=${teamId}&m=${member._id}`;
return (
@@ -44,13 +52,41 @@ export function MemberProgressItem(props: MemberProgressItemProps) {
/>