first commit

This commit is contained in:
2025-04-24 13:11:28 +08:00
commit ff9c54d5e4
5960 changed files with 834111 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
import '../marketing'
import ReactDOM from 'react-dom'
import { CompromisedPasswordCard } from '../features/compromised-password/components/compromised-password-root'
const compromisedPasswordContainer = document.getElementById(
'compromised-password'
)
if (compromisedPasswordContainer) {
ReactDOM.render(<CompromisedPasswordCard />, compromisedPasswordContainer)
}

View File

@@ -0,0 +1,23 @@
import '../utils/webpack-public-path' // configure dynamically loaded assets (via webpack) to be downloaded from CDN
import '../infrastructure/error-reporter' // set up error reporting, including Sentry
import '../infrastructure/hotjar' // set up Hotjar
import ReactDOM from 'react-dom'
import IdeRoot from '@/features/ide-react/components/ide-root'
ReactDOM.render(<IdeRoot />, document.getElementById('ide-root'))
// work around Safari 15's incomplete support for dvh units
// https://github.com/overleaf/internal/issues/18109
try {
if (
document.body.parentElement &&
document.body.parentElement?.clientHeight < document.body.clientHeight
) {
const rootElement = document.querySelector<HTMLDivElement>('#ide-root')
if (rootElement) {
rootElement.style.height = '100vh'
}
}
} catch {
// ignore errors
}

View File

@@ -0,0 +1,69 @@
import '../../marketing'
function homepageAnimation(homepageAnimationEl) {
function createFrames(word, { buildTime, holdTime, breakTime }) {
const frames = []
let current = ''
// Build up the word
for (const char of word) {
current += char
frames.push({ before: current, time: buildTime })
}
// Hold the complete word
frames.push({ before: current, time: holdTime })
// Break down the word
for (let i = word.length - 1; i > 0; i--) {
current = word.substring(0, i)
frames.push({ before: current, time: breakTime })
}
// Add the final frame with an empty string
frames.push({ before: '', time: breakTime })
return frames
}
const opts = {
buildTime: 100,
holdTime: 1000,
breakTime: 100,
}
const frames = [
// 1.5s pause before starting
{ before: '', time: 1500 },
...createFrames('articles', opts),
...createFrames('theses', opts),
...createFrames('reports', opts),
...createFrames('presentations', opts),
// 5s pause on 'anything' frame
...createFrames('anything', { ...opts, holdTime: 5000 }),
]
let index = 0
function nextFrame() {
const frame = frames[index]
index = (index + 1) % frames.length
homepageAnimationEl.innerHTML = frame.before
setTimeout(nextFrame, frame.time)
}
nextFrame()
}
const homepageAnimationEl = document.querySelector('#home-animation-text')
const reducedMotionReduce = window.matchMedia(
'(prefers-reduced-motion: reduce)'
)
if (homepageAnimationEl) {
if (reducedMotionReduce.matches) {
homepageAnimationEl.innerHTML = 'anything'
} else {
homepageAnimation(homepageAnimationEl)
}
}

View File

@@ -0,0 +1,14 @@
import './../utils/meta'
import '../utils/webpack-public-path'
import './../infrastructure/error-reporter'
import '@/i18n'
import '../features/event-tracking'
import '../features/cookie-banner'
import '../features/link-helpers/slow-link'
import ReactDOM from 'react-dom'
import ProjectListRoot from '../features/project-list/components/project-list-root'
const element = document.getElementById('project-list-root')
if (element) {
ReactDOM.render(<ProjectListRoot />, element)
}

View File

@@ -0,0 +1,11 @@
import './../utils/meta'
import '../utils/webpack-public-path'
import './../infrastructure/error-reporter'
import '@/i18n'
import ReactDOM from 'react-dom'
import SharingUpdatesRoot from '../features/token-access/components/sharing-updates-root'
const element = document.getElementById('sharing-updates-page')
if (element) {
ReactDOM.render(<SharingUpdatesRoot />, element)
}

View File

@@ -0,0 +1,10 @@
import '../marketing'
import ReactDOM from 'react-dom'
import { SocketDiagnostics } from '@/features/socket-diagnostics/components/socket-diagnostics'
const socketDiagnosticsContainer = document.getElementById('socket-diagnostics')
if (socketDiagnosticsContainer) {
ReactDOM.render(<SocketDiagnostics />, socketDiagnosticsContainer)
}

View File

@@ -0,0 +1,11 @@
import './../utils/meta'
import '../utils/webpack-public-path'
import './../infrastructure/error-reporter'
import '@/i18n'
import ReactDOM from 'react-dom'
import TokenAccessRoot from '../features/token-access/components/token-access-root'
const element = document.getElementById('token-access-page')
if (element) {
ReactDOM.render(<TokenAccessRoot />, element)
}

View File

@@ -0,0 +1,12 @@
import '../../marketing'
import ReactDOM from 'react-dom'
import { AddSecondaryEmailPrompt } from '../../features/settings/components/emails/add-secondary-email-prompt'
const addSecondaryEmailContainer = document.getElementById(
'add-secondary-email'
)
if (addSecondaryEmailContainer) {
ReactDOM.render(<AddSecondaryEmailPrompt />, addSecondaryEmailContainer)
}

View File

@@ -0,0 +1,10 @@
import '../../marketing'
import ReactDOM from 'react-dom'
import ConfirmSecondaryEmailForm from '../../features/settings/components/emails/confirm-secondary-email-form'
const confirmEmailContainer = document.getElementById('confirm-secondary-email')
if (confirmEmailContainer) {
ReactDOM.render(<ConfirmSecondaryEmailForm />, confirmEmailContainer)
}

View File

@@ -0,0 +1,18 @@
import '../../marketing'
import './../../utils/meta'
import '../../utils/webpack-public-path'
import './../../infrastructure/error-reporter'
import '@/i18n'
import '../../features/settings/components/root'
import ReactDOM from 'react-dom'
import SettingsPageRoot from '../../features/settings/components/root.tsx'
const element = document.getElementById('settings-page-root')
// For react-google-recaptcha
window.recaptchaOptions = {
enterprise: true,
useRecaptchaNet: true,
}
if (element) {
ReactDOM.render(<SettingsPageRoot />, element)
}

View File

@@ -0,0 +1,8 @@
import './../../../utils/meta'
import '../../../utils/webpack-public-path'
import './../../../infrastructure/error-reporter'
import '@/i18n'
import '../../../features/event-tracking'
import '../../../features/cookie-banner'
import '../../../features/link-helpers/slow-link'
import '../../../features/header-footer-react'

View File

@@ -0,0 +1,8 @@
import './base'
import ReactDOM from 'react-dom'
import Root from '../../../features/subscription/components/canceled-subscription/root'
const element = document.getElementById('subscription-canceled-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import './base'
import ReactDOM from 'react-dom'
import Root from '../../../features/subscription/components/dashboard/root'
const element = document.getElementById('subscription-dashboard-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import './base'
import ReactDOM from 'react-dom'
import GroupInvitesRoot from '@/features/subscription/components/group-invites/group-invites-root'
const element = document.getElementById('group-invites-root')
if (element) {
ReactDOM.render(<GroupInvitesRoot />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import Root from '@/features/group-management/components/add-seats/root'
const element = document.getElementById('add-seats-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import Root from '../../../../features/group-management/components/group-managers'
const element = document.getElementById('subscription-manage-group-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,17 @@
import '../base'
import ReactDOM from 'react-dom'
import GroupMembers from '../../../../features/group-management/components/group-members'
import { GroupMembersProvider } from '../../../../features/group-management/context/group-members-context'
import { SplitTestProvider } from '@/shared/context/split-test-context'
const element = document.getElementById('subscription-manage-group-root')
if (element) {
ReactDOM.render(
<SplitTestProvider>
<GroupMembersProvider>
<GroupMembers />
</GroupMembersProvider>
</SplitTestProvider>,
element
)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import Root from '../../../../features/group-management/components/institution-managers'
const element = document.getElementById('subscription-manage-group-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import ManuallyCollectedSubscription from '@/features/group-management/components/manually-collected-subscription'
const element = document.getElementById('manually-collected-subscription-root')
if (element) {
ReactDOM.render(<ManuallyCollectedSubscription />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import MissingBillingInformation from '@/features/group-management/components/missing-billing-information'
const element = document.getElementById('missing-billing-information-root')
if (element) {
ReactDOM.render(<MissingBillingInformation />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import Root from '../../../../features/group-management/components/publisher-managers'
const element = document.getElementById('subscription-manage-group-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import SubtotalLimitExceeded from '@/features/group-management/components/subtotal-limit-exceeded'
const element = document.getElementById('subtotal-limit-exceeded-root')
if (element) {
ReactDOM.render(<SubtotalLimitExceeded />, element)
}

View File

@@ -0,0 +1,8 @@
import '../base'
import ReactDOM from 'react-dom'
import Root from '@/features/group-management/components/upgrade-subscription/root'
const element = document.getElementById('upgrade-group-subscription-root')
if (element) {
ReactDOM.render(<Root />, element)
}

View File

@@ -0,0 +1,8 @@
import './base'
import ReactDOM from 'react-dom'
import InvitedManagedRoot from '../../../features/subscription/components/invite-managed-root'
const element = document.getElementById('invite-managed-root')
if (element) {
ReactDOM.render(<InvitedManagedRoot />, element)
}

View File

@@ -0,0 +1,9 @@
import './base'
import ReactDOM from 'react-dom'
import InviteRoot from '@/features/subscription/components/invite-root'
const element = document.getElementById('invite-root')
if (element) {
ReactDOM.render(<InviteRoot />, element)
}

View File

@@ -0,0 +1,8 @@
import '@/marketing'
import ReactDOM from 'react-dom'
import PreviewSubscriptionChange from '@/features/subscription/components/preview-subscription-change/root'
const element = document.getElementById('subscription-preview-change')
if (element) {
ReactDOM.render(<PreviewSubscriptionChange />, element)
}

View File

@@ -0,0 +1,8 @@
import './base'
import ReactDOM from 'react-dom'
import Root from '../../../features/subscription/components/successful-subscription/root'
const element = document.getElementById('subscription-success-root')
if (element) {
ReactDOM.render(<Root />, element)
}