US-001: Remove unused legacy components and hooks
Delete 23 dead files: old portfolio components (Contact, Education, Experience, FloatingNav, Footer, Hero, Projects, Skills), legacy PMR components (PMRInterface, PatientBanner, ClinicalSidebar, Breadcrumb, MobileBottomNav), all 7 views/ directory files, and 3 unused hooks (useScrollCondensation, useActiveSection, useScrollReveal). No imports referenced any of these files — clean removal with zero build or type errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
import { useEffect, useState, useRef, useCallback } from 'react'
|
||||
|
||||
const SECTION_IDS = ['about', 'skills', 'experience', 'education', 'projects', 'contact'] as const
|
||||
|
||||
type SectionId = typeof SECTION_IDS[number]
|
||||
|
||||
export function useActiveSection(): SectionId {
|
||||
const [activeSection, setActiveSection] = useState<SectionId>('about')
|
||||
const observerRef = useRef<IntersectionObserver | null>(null)
|
||||
const visibleSectionsRef = useRef<Map<string, number>>(new Map())
|
||||
|
||||
const handleIntersect = useCallback((entries: IntersectionObserverEntry[]) => {
|
||||
entries.forEach((entry) => {
|
||||
const sectionId = entry.target.id
|
||||
if (SECTION_IDS.includes(sectionId as SectionId)) {
|
||||
if (entry.isIntersecting) {
|
||||
visibleSectionsRef.current.set(sectionId, entry.intersectionRatio)
|
||||
} else {
|
||||
visibleSectionsRef.current.delete(sectionId)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const visibleEntries = Array.from(visibleSectionsRef.current.entries())
|
||||
if (visibleEntries.length > 0) {
|
||||
visibleEntries.sort((a, b) => {
|
||||
const indexA = SECTION_IDS.indexOf(a[0] as SectionId)
|
||||
const indexB = SECTION_IDS.indexOf(b[0] as SectionId)
|
||||
return indexA - indexB
|
||||
})
|
||||
|
||||
const topSection = visibleEntries[0][0] as SectionId
|
||||
setActiveSection(topSection)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
observerRef.current = new IntersectionObserver(handleIntersect, {
|
||||
rootMargin: '-20% 0px -70% 0px',
|
||||
threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
|
||||
})
|
||||
|
||||
SECTION_IDS.forEach((id) => {
|
||||
const element = document.getElementById(id)
|
||||
if (element && observerRef.current) {
|
||||
observerRef.current.observe(element)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
if (observerRef.current) {
|
||||
observerRef.current.disconnect()
|
||||
}
|
||||
}
|
||||
}, [handleIntersect])
|
||||
|
||||
return activeSection
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
|
||||
interface UseScrollCondensationOptions {
|
||||
threshold?: number
|
||||
scrollContainer?: HTMLElement | null
|
||||
}
|
||||
|
||||
export function useScrollCondensation(options: UseScrollCondensationOptions = {}) {
|
||||
const { threshold = 100, scrollContainer } = options
|
||||
const [isCondensed, setIsCondensed] = useState(false)
|
||||
|
||||
const handleScroll = useCallback(() => {
|
||||
if (!scrollContainer) return
|
||||
setIsCondensed(scrollContainer.scrollTop >= threshold)
|
||||
}, [scrollContainer, threshold])
|
||||
|
||||
useEffect(() => {
|
||||
if (!scrollContainer) return
|
||||
|
||||
scrollContainer.addEventListener('scroll', handleScroll, { passive: true })
|
||||
// Check initial state
|
||||
handleScroll()
|
||||
|
||||
return () => {
|
||||
scrollContainer.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [scrollContainer, handleScroll])
|
||||
|
||||
return { isCondensed }
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { useEffect, useRef, useState, type RefObject } from 'react'
|
||||
|
||||
interface UseScrollRevealOptions {
|
||||
threshold?: number
|
||||
rootMargin?: string
|
||||
triggerOnce?: boolean
|
||||
}
|
||||
|
||||
export function useScrollReveal<T extends HTMLElement>(
|
||||
options: UseScrollRevealOptions = {}
|
||||
): [RefObject<T>, boolean] {
|
||||
const { threshold = 0.15, rootMargin = '0px', triggerOnce = true } = options
|
||||
const ref = useRef<T>(null)
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const element = ref.current
|
||||
if (!element) return
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true)
|
||||
if (triggerOnce) {
|
||||
observer.unobserve(element)
|
||||
}
|
||||
} else if (!triggerOnce) {
|
||||
setIsVisible(false)
|
||||
}
|
||||
},
|
||||
{ threshold, rootMargin }
|
||||
)
|
||||
|
||||
observer.observe(element)
|
||||
|
||||
return () => observer.disconnect()
|
||||
}, [threshold, rootMargin, triggerOnce])
|
||||
|
||||
return [ref, isVisible]
|
||||
}
|
||||
Reference in New Issue
Block a user