Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions app/expert-finder/lib/generatedEmailStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ export function isGeneratedEmailBounced(status: string): boolean {
return status === 'bounced';
}

export function isGeneratedEmailFailed(status: string): boolean {
return status === 'failed' || status === 'send_failed';
}

export type GeneratedEmailStatusBadgeVariant =
| 'default'
| 'primary'
Expand Down
1 change: 0 additions & 1 deletion app/expert-finder/library/new/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
const INPUT_TYPES: InputType[] = ['abstract', 'pdf', 'full_content'];

export const EXPERT_COUNT_OPTIONS = [5, 10, 25, 50, 100] as const;
export type ExpertCountOption = (typeof EXPERT_COUNT_OPTIONS)[number];

export const DEFAULT_STATE = 'All States';

Expand Down
2 changes: 0 additions & 2 deletions app/layouts/MobileBottomNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,3 @@ export const MobileBottomNav: React.FC = () => {
</nav>
);
};

export default MobileBottomNav;
2 changes: 0 additions & 2 deletions app/leaderboard/components/LeaderboardContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import { useCurrentUserLeaderboard } from '@/hooks/useLeaderboard';
import { TopPeerReviewers } from './TopPeerReviewers';
import { TopFunders } from './TopFunders';

export type { LeaderboardPeriod } from '@/services/leaderboard.service';

const PERIOD_OPTIONS: { value: LeaderboardPeriod; label: string }[] = [
{ value: '7_days', label: 'Last 7 Days' },
{ value: '30_days', label: 'Last 30 Days' },
Expand Down
8 changes: 0 additions & 8 deletions app/pool/doublezero/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@ export const SURFACE_KM = EARTH_RADIUS_KM * CENTRAL_ANGLE;
/** Straight-line distance between the endpoints, through the planet. */
export const CHORD_KM = 2 * EARTH_RADIUS_KM * Math.sin(CENTRAL_ANGLE / 2);

/** How far below the surface that chord dips at its midpoint. */
export const CHORD_DEPTH_KM = EARTH_RADIUS_KM * (1 - Math.cos(CENTRAL_ANGLE / 2));

/** Closest the chord comes to the Earth's centre. Under 80 km, so: inner core. */
export const CHORD_CENTRE_MISS_KM = EARTH_RADIUS_KM * Math.cos(CENTRAL_ANGLE / 2);

/**
* A neutrino crosses the chord at c. It has mass, so strictly it is a hair
* slower — but at the TeV energies this RFP contemplates the deficit is
Expand All @@ -66,8 +60,6 @@ export const CHORD_MS = (CHORD_KM / C_KM_S) * 1000;
/** Fiber pays twice — the longer path and the slower medium. */
export const SURFACE_MS = ((SURFACE_KM * FIBER_INDEX) / C_KM_S) * 1000;

export const SAVED_MS = SURFACE_MS - CHORD_MS;

/**
* Shell boundaries by depth, as fractions of the radius, for the cross-section.
* Upper/lower mantle at 660 km, the core-mantle boundary at 2,890 km, and the
Expand Down
6 changes: 0 additions & 6 deletions components/Activity/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// Cards
export { ActivityCard } from './cards/ActivityCard';
export { ActivityCardCompact } from './cards/ActivityCardCompact';
export { ActivityCardHeader } from './cards/ActivityCardHeader';
export { ActivityCardSkeleton } from './cards/ActivityCardSkeleton';
export { ActivityCommentGroupCard } from './cards/ActivityCommentGroupCard';
export { ActivityFundingGroupCard } from './cards/ActivityFundingGroupCard';

// Work card primitives, shared with the funding feeds
export { ActivityTimestamp } from './cards/ActivityTimestamp';
Expand All @@ -16,9 +12,7 @@ export { WorkPreviewCard } from './work/WorkPreviewCard';
export { ActivityFeedList } from './ActivityFeedList';
export { ActivityRow } from './ActivityRow';
export { ActivityPageContent } from './ActivityPageContent';
export { ActivityCacheBypassControl } from './ActivityCacheBypassControl';

// Sidebar
export { ActivitySidebar } from './sidebar/ActivitySidebar';
export { ActivitySidebarServer } from './sidebar/ActivitySidebarServer';
export { ActivitySidebarSkeleton } from './sidebar/ActivitySidebarSkeleton';
2 changes: 0 additions & 2 deletions components/Auth/AuthContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import ForgotPassword from './screens/ForgotPassword';
import { AuthScreen, type AuthAppearance, type CatalystSurface } from './types';
import AnalyticsService, { LogEvent } from '@/services/analytics.service';

export type { AuthAppearance, CatalystSurface } from './types';

interface AuthContentProps {
onClose?: () => void;
onSuccess?: () => void;
Expand Down
272 changes: 0 additions & 272 deletions components/Bounty/lib/bountyUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,6 @@ export const countClosedBounties = (bounties: Bounty[]): number => {
return getClosedBounties(bounties).length;
};

/**
* Calculates the total amount of all bounties in an array
* @param bounties Array of bounties to sum
* @returns Total amount as a number
*/
export const calculateTotalBountyAmount = (bounties: Bounty[]): number => {
return bounties.reduce((sum, bounty) => sum + parseFloat(bounty.amount), 0);
};

/**
* Finds the first active (open) bounty in an array
* @param bounties Array of bounties to search
Expand Down Expand Up @@ -113,22 +104,6 @@ export const findClosedBounty = (bounties: Bounty[]): Bounty | undefined => {
return closedBounty;
};

/**
* Gets the bounty to display from an array of bounties
* @param bounties Array of bounties
* @returns The display bounty or undefined if none found
*/
export const getDisplayBounty = (bounties: Bounty[]): Bounty | undefined => {
if (!bounties || !Array.isArray(bounties) || bounties.length === 0) {
return undefined;
}

const activeBounty = findActiveBounty(bounties);
const closedBounty = findClosedBounty(bounties);

return activeBounty || closedBounty;
};

/**
* Checks if a bounty is expiring soon (within 3 days)
* @param expirationDate The expiration date string
Expand All @@ -151,22 +126,6 @@ export const isExpiringSoon = (expirationDate?: string, daysThreshold: number =
return diffDays > 0 && diffDays < daysThreshold;
};

/**
* Gets the appropriate title for a bounty based on its type and status
* @param bounty The bounty object
* @param isOpen Whether the bounty is open
* @returns The appropriate title string
*/
export const getBountyTitle = (bounty?: Bounty, isOpen?: boolean): string => {
if (bounty?.bountyType === 'REVIEW') {
return isOpen ? 'Bounty: Peer Review' : 'Awarded Bounty: Peer Review';
}
if (bounty?.bountyType === 'ANSWER') {
return isOpen ? 'Bounty: Answer to Question' : 'Awarded Bounty: Answer to Question';
}
return isOpen ? 'Bounty' : 'Awarded Bounty';
};

/**
* Calculates the total awarded amount for a bounty with solutions
* @param bounty The bounty object with solutions
Expand Down Expand Up @@ -194,157 +153,6 @@ export interface Contributor {
isCreator?: boolean;
}

/**
* Formats contributor names for display
* @param contributors Array of contributors
* @returns Formatted string of contributor names
*/
export const formatContributorNames = (contributors: Contributor[]): string => {
if (contributors.length === 0) return 'Unknown';

// Find the creator first (the main bounty creator)
const creator = contributors.find((c) => c.isCreator);
const creatorName = creator?.profile.fullName || contributors[0]?.profile.fullName || 'Unknown';

// Get all non-creator contributors
const otherContributors = contributors.filter(
(c) => c.profile.fullName !== creatorName && c.profile.fullName
);

if (contributors.length === 1) {
// Case 1: Just one contributor
return creatorName;
} else if (contributors.length === 2) {
// Case 2: Two contributors
const otherContributor = otherContributors[0];
return `${creatorName} and ${otherContributor?.profile.fullName || 'another contributor'}`;
} else {
// Case 3: More than two contributors
if (otherContributors.length === 0) {
return `${creatorName} and others`;
} else if (otherContributors.length === 1) {
return `${creatorName} and ${otherContributors[0].profile.fullName}`;
} else {
return `${creatorName}, ${otherContributors[0].profile.fullName} and ${
otherContributors.length > 1 ? `${otherContributors.length - 1} others` : 'another'
}`;
}
}
};

/**
* Extracts all contributors from an array of bounties
* @param bounties Array of bounties
* @param displayBounty The main bounty being displayed
* @returns Array of contributors with profile information
*/
export const extractContributors = (bounties: Bounty[], displayBounty?: Bounty): Contributor[] => {
return bounties
.filter((bounty) => bounty.createdBy.authorProfile)
.map((bounty) => {
// A bounty is not a contribution if it doesn't have a parent bounty
const isContribution = bounty.raw && !!bounty.raw.parent;

return {
profile: bounty.createdBy.authorProfile!,
amount: Number(bounty.amount),
isCreator: bounty.id === displayBounty?.id && !isContribution,
};
});
};

/**
* Filters out the creator from the contributors list
* @param contributors Array of contributors
* @returns Array of contributors without the creator
*/
export const filterOutCreator = (contributors: Contributor[]): Contributor[] => {
return contributors.filter((contributor) => !contributor.isCreator);
};

/**
* Extracts contributors for display in the UI based on the following rules:
* 1. If there are no contributors (other than the creator), return an empty array
* 2. If there are one or more contributors, return both the creator and the contributors
*
* @param bounty The bounty to extract contributors from
* @returns Array of contributors for display
*/
export const extractContributorsForDisplay = (bounty: Bounty): Contributor[] => {
// If there are no contributions, return an empty array
if (!bounty.contributions || bounty.contributions.length === 0) {
return [];
}

// Process contributions directly from the bounty.contributions array
const contributorsFromContributions = bounty.contributions.map((contribution) => {
// Get the name from the contribution's createdBy
let fullName = 'Unknown';
let profileImage: string | undefined = undefined;

// Try to get profile info from authorProfile if it exists
if (contribution.createdBy.authorProfile) {
fullName = contribution.createdBy.authorProfile.fullName || 'Unknown';
profileImage = contribution.createdBy.authorProfile.profileImage;
}
// Fallback to raw data if available
else if (contribution.raw?.created_by?.author_profile) {
const rawProfile = contribution.raw.created_by.author_profile;
fullName = `${rawProfile.first_name || ''} ${rawProfile.last_name || ''}`.trim() || 'Unknown';
profileImage = rawProfile.profile_image;
}

return {
profile: {
fullName,
profileImage,
isClaimed: true,
},
amount: Number(contribution.amount),
isCreator: false,
};
});

// Add the creator as a contributor if not already included
let creatorFullName = 'Unknown';
let creatorProfileImage: string | undefined = undefined;

// Try to get creator profile info from authorProfile if it exists
if (bounty.createdBy.authorProfile) {
creatorFullName = bounty.createdBy.authorProfile.fullName || 'Unknown';
creatorProfileImage = bounty.createdBy.authorProfile.profileImage;
}
// Fallback to raw data if available
else if (bounty.raw?.created_by?.author_profile) {
const rawProfile = bounty.raw.created_by.author_profile;
creatorFullName =
`${rawProfile.first_name || ''} ${rawProfile.last_name || ''}`.trim() || 'Unknown';
creatorProfileImage = rawProfile.profile_image;
}

const creator: Contributor = {
profile: {
fullName: creatorFullName,
profileImage: creatorProfileImage,
isClaimed: true,
},
amount: Number(bounty.amount),
isCreator: true,
};

// Check if the creator is already in the contributors list
const creatorAlreadyIncluded = contributorsFromContributions.some(
(c) => c.profile.fullName === creator.profile.fullName
);

// Return all contributors including the creator (if not already included)
const result = creatorAlreadyIncluded
? contributorsFromContributions
: [...contributorsFromContributions, creator];

return result;
};

/**
* Checks if a comment has any bounties
* @param comment The comment object to check
Expand All @@ -362,77 +170,6 @@ export interface BountyAvatar {
authorId?: number;
}

/**
* Extracts avatar information from bounties for use in UI components
* @param bounties Array of bounties to extract avatars from
* @param openOnly Whether to only include open bounties (default: true)
* @returns Array of avatar objects ready for display
*/
export const extractBountyAvatars = (
bounties: Bounty[],
openOnly: boolean = true
): BountyAvatar[] => {
// Filter bounties if openOnly is true
const filteredBounties = openOnly
? bounties.filter((bounty) => bounty.status === 'OPEN')
: bounties;

// Extract avatars from each bounty
const avatars = filteredBounties.flatMap((bounty) => {
const result = [];

// Add creator avatar if available
if (bounty.createdBy) {
// Try to access profile information from raw data
const creatorRaw = bounty.raw?.created_by || {};
const authorProfile = bounty.createdBy.authorProfile || {};

// Use explicit type casting to avoid TypeScript errors with optional fields
const profileImage = (authorProfile as any).profileImage || (creatorRaw as any).profile_image;
const fullName = (authorProfile as any).fullName || (creatorRaw as any).full_name;
const id = (authorProfile as any).id || (creatorRaw as any).id;

result.push({
src: profileImage || '/images/default-avatar.png',
alt: fullName || 'Creator',
tooltip: fullName,
authorId: id,
});
}

// Add contributor avatars if available
if (bounty.contributions && bounty.contributions.length > 0) {
const contributorAvatars = bounty.contributions.map((contribution) => {
const contributorRaw = contribution.raw?.user?.author_profile || {};
const authorProfile = contribution.createdBy?.authorProfile || {};

// Use explicit type casting to avoid TypeScript errors with optional fields
const profileImage =
(authorProfile as any).profileImage || (contributorRaw as any).profile_image;
const fullName = (authorProfile as any).fullName || (contributorRaw as any).full_name;
const id = (authorProfile as any).id || (contributorRaw as any).id;

return {
src: profileImage || '/images/default-avatar.png',
alt: fullName || 'Contributor',
tooltip: fullName,
authorId: id,
};
});

result.push(...contributorAvatars);
}

return result;
});

// Remove duplicates by authorId
return avatars.filter(
(avatar, index, self) =>
avatar.authorId && index === self.findIndex((a) => a.authorId === avatar.authorId)
);
};

/**
* Hacky shim to ensure we are rendering $150 USD for Foundation bounties.
* Extracts the user ID of the bounty creator from various possible data structures.
Expand Down Expand Up @@ -549,15 +286,6 @@ export const calculateBountyDisplayAmountUSD = (bounty: Bounty, exchangeRate: nu
return Math.round(rscAmount * exchangeRate);
};

export const calculateTotalBountyDisplayAmountUSD = (
bounties: Bounty[],
exchangeRate: number
): number => {
return bounties.reduce((total, bounty) => {
return total + calculateBountyDisplayAmountUSD(bounty, exchangeRate);
}, 0);
};

/**
* Calculates the display amount for a bounty, returning either USD or RSC based on preference.
* For Foundation bounties displayed in USD, returns a flat $150.
Expand Down
Loading
Loading