Adds AuthContext with Orval API integration, user login/logout/register flows, and account settings page. Refactors navigation and layouts to use authentication context. Introduces new account-related pages (Login, Register, Logout, AccountSettings), updates PrivateRoute to use AuthContext, and improves error handling in Downloader. Removes obsolete context example and adds comprehensive usage documentation for AuthContext.
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import { StrictMode } from 'react'
|
|
import { createRoot } from 'react-dom/client'
|
|
import { AuthProvider } from './context/AuthContext'
|
|
import './index.css'
|
|
import App from './App.tsx'
|
|
|
|
createRoot(document.getElementById('root')!).render(
|
|
<StrictMode>
|
|
<AuthProvider>
|
|
<App />
|
|
</AuthProvider>
|
|
</StrictMode>,
|
|
)
|
|
|
|
// Lightweight scroll-reveal setup for elements with `.section` or `[data-reveal]`.
|
|
// Respects prefers-reduced-motion and observes dynamically added nodes.
|
|
function setupReveal() {
|
|
const w = window as unknown as { __revealSetupDone?: boolean }
|
|
if (w.__revealSetupDone) return
|
|
w.__revealSetupDone = true
|
|
|
|
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
const selector = '.section, [data-reveal]'
|
|
|
|
// If reduced motion is preferred, mark everything visible and skip observers
|
|
if (prefersReduced) {
|
|
document.querySelectorAll(selector).forEach((el) => el.classList.add('reveal-visible'))
|
|
return
|
|
}
|
|
|
|
const seen = new WeakSet<Element>()
|
|
const io = new IntersectionObserver(
|
|
(entries) => {
|
|
for (const entry of entries) {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('reveal-visible')
|
|
io.unobserve(entry.target)
|
|
}
|
|
}
|
|
},
|
|
{ threshold: 0.12, rootMargin: '0px 0px -10% 0px' },
|
|
)
|
|
|
|
const observeExisting = () => {
|
|
document.querySelectorAll(selector).forEach((el) => {
|
|
if (!seen.has(el)) {
|
|
seen.add(el)
|
|
io.observe(el)
|
|
}
|
|
})
|
|
}
|
|
|
|
// Observe current DOM
|
|
observeExisting()
|
|
|
|
// Observe future DOM mutations (e.g., route changes render new sections)
|
|
const mo = new MutationObserver((mutations) => {
|
|
let needsScan = false
|
|
for (const m of mutations) {
|
|
if (m.type === 'childList' && (m.addedNodes?.length ?? 0) > 0) {
|
|
needsScan = true
|
|
}
|
|
if (needsScan) break
|
|
}
|
|
if (needsScan) observeExisting()
|
|
})
|
|
mo.observe(document.documentElement, { childList: true, subtree: true })
|
|
|
|
// Cleanup on HMR disposal (Vite dev) to avoid duplicate observers
|
|
if (import.meta && import.meta.hot) {
|
|
import.meta.hot.dispose(() => {
|
|
io.disconnect()
|
|
mo.disconnect()
|
|
w.__revealSetupDone = false
|
|
})
|
|
}
|
|
}
|
|
|
|
// Initialize after first render tick
|
|
queueMicrotask(setupReveal)
|