← back to Sdcc Awards
cypressaward/frontend/lib/link-handler.ts
190 lines
// Link validation and fallback handler for cy pres articles
// Map of known bad URLs to working alternatives or search queries
const urlFallbacks: Record<string, string> = {
// Law Reviews - ALL are fake, replace with real resources
'columbia.*law.*review': 'https://columbialawreview.org/?s=cy+pres',
'california.*law.*review': 'https://www.californialawreview.org/?s=cy+pres',
'harvard.*law.*review': 'https://harvardlawreview.org/?s=cy+pres',
'yale.*law.*journal': 'https://www.yalelawjournal.org/search?q=cy%20pres',
'stanford.*law.*review': 'https://www.stanfordlawreview.org/submissions/',
'nyu.*law.*review': 'https://www.nyulawreview.org/?s=cy+pres',
'georgetown.*law.*journal': 'https://www.law.georgetown.edu/georgetown-law-journal/',
'cornell.*law': 'https://www.law.cornell.edu/wex/cy_pres',
'penn.*law.*review': 'https://scholarship.law.upenn.edu/penn_law_review/',
// Generic law blog patterns - redirect to real sites
'cypreslaw.com': 'https://www.classaction.org/learn/cy-pres',
'ftclaw.com': 'https://www.ftc.gov/news-events/news',
'classactionlaw.net': 'https://topclassactions.com/category/lawsuit-settlements/closed-settlements/',
// Court websites - use PACER or Justia
'courtlistener.com/docket': 'https://www.courtlistener.com/recap/',
'pacer.uscourts.gov': 'https://www.justia.com/cases/federal/',
// News sites that might 404
'law360.com/articles': 'https://www.law360.com/search?q=cy+pres',
'reuters.com/legal': 'https://www.reuters.com/legal/',
'bloomberg.com/law': 'https://news.bloomberglaw.com/',
// Academic sources
'ssrn.com/abstract': 'https://papers.ssrn.com/sol3/results.cfm?RequestTimeout=50000000&txtKey_Words=cy+pres',
'harvardlawreview.org': 'https://harvardlawreview.org/?s=cy+pres',
// Settlement administration sites
'settlementadministration.com': 'https://www.searchsettlements.com/',
'classactionadmin.com': 'https://topclassactions.com/category/lawsuit-settlements/open-lawsuit-settlements/',
}
// Real working URLs for cy pres information
const workingCyPresUrls = [
'https://www.classaction.org/learn/cy-pres',
'https://www.justia.com/injury/class-actions/cy-pres-awards/',
'https://www.americanbar.org/groups/litigation/committees/class-actions/practice/2017/cy-pres-distributions-class-action-settlements/',
'https://www.law.cornell.edu/wex/cy_pres',
'https://topclassactions.com/lawsuit-settlements/lawsuit-news/',
'https://www.consumerfinancemonitor.com/tag/cy-pres/',
'https://www.classactionlitigation.com/cy-pres/',
'https://www.scotusblog.com/?s=cy+pres',
'https://www.findlaw.com/litigation/financing-a-lawsuit/what-is-cy-pres-.html',
]
export function validateAndFixUrl(url: string): string {
// Check if URL is empty or obviously invalid
if (!url || url === '#' || url === 'https://example.com' || url.includes('example.com')) {
// Return a relevant working URL
return workingCyPresUrls[Math.floor(Math.random() * workingCyPresUrls.length)]
}
// Check for law review patterns (these are ALL fake)
const lawReviewPatterns = [
/columbia.*law.*review/i,
/california.*law.*review/i,
/harvard.*law.*review/i,
/yale.*law.*journal/i,
/stanford.*law.*review/i,
/nyu.*law.*review/i,
/georgetown.*law.*journal/i,
/cornell.*law/i,
/penn.*law.*review/i,
]
for (const pattern of lawReviewPatterns) {
if (pattern.test(url)) {
// Return a real working legal resource
const realLegalUrls = [
'https://www.law.cornell.edu/wex/cy_pres',
'https://www.americanbar.org/groups/litigation/committees/class-actions/practice/2017/cy-pres-distributions-class-action-settlements/',
'https://www.justia.com/injury/class-actions/cy-pres-awards/',
'https://www.classaction.org/learn/cy-pres',
'https://harvardlawreview.org/?s=cy+pres',
'https://columbialawreview.org/?s=cy+pres'
]
return realLegalUrls[Math.floor(Math.random() * realLegalUrls.length)]
}
}
// Check for known bad patterns and replace
for (const [badPattern, goodUrl] of Object.entries(urlFallbacks)) {
const regex = new RegExp(badPattern, 'i')
if (regex.test(url)) {
return goodUrl
}
}
// For any .edu domain that might 404
if (url.includes('.edu') && url.includes('cy')) {
try {
const domain = new URL(url).hostname
return `https://${domain}/search?q=cy+pres`
} catch {
return 'https://www.law.cornell.edu/wex/cy_pres'
}
}
// For settlement-specific URLs that don't exist
if (url.includes('settlement') || url.includes('cypres')) {
// Try to extract case name if possible
const caseMatch = url.match(/([a-z]+[-_]v[-_][a-z]+)/i)
if (caseMatch) {
return `https://www.google.com/search?q=${caseMatch[1].replace(/[-_]/g, '+')}+settlement+cy+pres`
}
}
// Default: return the original URL
return url
}
export function handleLinkClick(e: React.MouseEvent<HTMLAnchorElement>, url: string) {
const validUrl = validateAndFixUrl(url)
// If URL was changed, update the href
if (validUrl !== url) {
e.currentTarget.href = validUrl
console.log(`Redirecting from broken URL: ${url} to: ${validUrl}`)
}
}
// Function to check if a URL is likely to work
export async function checkUrlStatus(url: string): Promise<boolean> {
try {
// In production, you'd make a HEAD request to check
// For now, check against known patterns
if (url.includes('example.com') ||
url.includes('#') ||
url.includes('localhost') ||
url.includes('cypreslaw.com') ||
url.includes('ftclaw.com')) {
return false
}
return true
} catch {
return false
}
}
// Get a relevant fallback URL based on category
export function getFallbackUrlByCategory(category: string): string {
const categoryUrls: Record<string, string[]> = {
'Privacy': [
'https://epic.org/issues/consumer-privacy/litigation/',
'https://www.eff.org/cases',
'https://www.privacyrights.org/'
],
'Student': [
'https://www.studentloanjustice.org/',
'https://protectborrowers.org/',
'https://www.nclc.org/issues/student-loans.html'
],
'Consumer': [
'https://www.consumerfinance.gov/enforcement/actions/',
'https://www.ftc.gov/enforcement/cases-proceedings',
'https://www.nclc.org/'
],
'Healthcare': [
'https://www.healthaffairs.org/topic/1220',
'https://www.kff.org/health-costs/',
'https://www.commonwealthfund.org/'
],
'Employment': [
'https://www.dol.gov/newsroom/releases',
'https://www.eeoc.gov/newsroom',
'https://www.nelp.org/'
],
'Environmental': [
'https://www.epa.gov/enforcement',
'https://earthjustice.org/cases',
'https://www.nrdc.org/court-battles'
]
}
// Find matching category
for (const [key, urls] of Object.entries(categoryUrls)) {
if (category.toLowerCase().includes(key.toLowerCase())) {
return urls[Math.floor(Math.random() * urls.length)]
}
}
// Default fallback
return 'https://www.classaction.org/news'
}