mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
feat(404): added 404 page (#1401)
* feat(404): added 404 page * use provided brand support email over default sim one
This commit is contained in:
@@ -5,6 +5,7 @@ import { CheckCircle2, Mail, RotateCcw, ShieldX, UserPlus, Users2 } from 'lucide
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { LoadingAgent } from '@/components/ui/loading-agent'
|
||||
import { useBrandConfig } from '@/lib/branding/branding'
|
||||
import { inter } from '@/app/fonts/inter'
|
||||
import { soehne } from '@/app/fonts/soehne/soehne'
|
||||
|
||||
@@ -57,6 +58,7 @@ export function InviteStatusCard({
|
||||
}: InviteStatusCardProps) {
|
||||
const router = useRouter()
|
||||
const [buttonClass, setButtonClass] = useState('auth-button-gradient')
|
||||
const brandConfig = useBrandConfig()
|
||||
|
||||
useEffect(() => {
|
||||
const checkCustomBrand = () => {
|
||||
@@ -116,11 +118,6 @@ export function InviteStatusCard({
|
||||
return (
|
||||
<div className={`${soehne.className} space-y-6`}>
|
||||
<div className='space-y-1 text-center'>
|
||||
{IconComponent && (
|
||||
<div className={`mx-auto mb-4 w-fit rounded-full p-3 ${iconBg}`}>
|
||||
<IconComponent className={`h-8 w-8 ${iconColor}`} />
|
||||
</div>
|
||||
)}
|
||||
<h1 className='font-medium text-[32px] text-black tracking-tight'>{title}</h1>
|
||||
<p className={`${inter.className} font-[380] text-[16px] text-muted-foreground`}>
|
||||
{description}
|
||||
@@ -172,7 +169,7 @@ export function InviteStatusCard({
|
||||
>
|
||||
Need help?{' '}
|
||||
<a
|
||||
href='mailto:help@sim.ai'
|
||||
href={`mailto:${brandConfig.supportEmail}`}
|
||||
className='auth-link underline-offset-4 transition hover:underline'
|
||||
>
|
||||
Contact support
|
||||
|
||||
90
apps/sim/app/not-found.tsx
Normal file
90
apps/sim/app/not-found.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { useBrandConfig } from '@/lib/branding/branding'
|
||||
import AuthBackground from '@/app/(auth)/components/auth-background'
|
||||
import Nav from '@/app/(landing)/components/nav/nav'
|
||||
|
||||
function isColorDark(hexColor: string): boolean {
|
||||
const hex = hexColor.replace('#', '')
|
||||
const r = Number.parseInt(hex.substring(0, 2), 16)
|
||||
const g = Number.parseInt(hex.substring(2, 4), 16)
|
||||
const b = Number.parseInt(hex.substring(4, 6), 16)
|
||||
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
|
||||
return luminance < 0.5
|
||||
}
|
||||
|
||||
export default function NotFound() {
|
||||
const [buttonClass, setButtonClass] = useState('auth-button-gradient')
|
||||
const brandConfig = useBrandConfig()
|
||||
|
||||
useEffect(() => {
|
||||
const rootStyle = getComputedStyle(document.documentElement)
|
||||
const brandBackground = rootStyle.getPropertyValue('--brand-background-hex').trim()
|
||||
|
||||
if (brandBackground && isColorDark(brandBackground)) {
|
||||
document.body.classList.add('auth-dark-bg')
|
||||
} else {
|
||||
document.body.classList.remove('auth-dark-bg')
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const checkCustomBrand = () => {
|
||||
const computedStyle = getComputedStyle(document.documentElement)
|
||||
const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim()
|
||||
if (brandAccent && brandAccent !== '#6f3dfa') {
|
||||
setButtonClass('auth-button-custom')
|
||||
} else {
|
||||
setButtonClass('auth-button-gradient')
|
||||
}
|
||||
}
|
||||
checkCustomBrand()
|
||||
window.addEventListener('resize', checkCustomBrand)
|
||||
const observer = new MutationObserver(checkCustomBrand)
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['style', 'class'],
|
||||
})
|
||||
return () => {
|
||||
window.removeEventListener('resize', checkCustomBrand)
|
||||
observer.disconnect()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<AuthBackground>
|
||||
<main className='relative flex min-h-screen flex-col font-geist-sans text-foreground'>
|
||||
{/* Header */}
|
||||
<Nav hideAuthButtons={true} variant='auth' />
|
||||
|
||||
{/* Content */}
|
||||
<div className='relative z-30 flex flex-1 items-center justify-center px-4 pb-24'>
|
||||
<div className='text-center'>
|
||||
<div className='mb-4 font-bold text-8xl text-foreground'>404</div>
|
||||
<div className='mb-8'>
|
||||
<Button
|
||||
asChild
|
||||
className={`${buttonClass} flex w-full items-center justify-center gap-2 rounded-[10px] border font-medium text-[15px] text-white transition-all duration-200`}
|
||||
>
|
||||
<Link href='/'>Back to Workspace</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className='text-center text-muted-foreground text-sm'>
|
||||
Need help?{' '}
|
||||
<a
|
||||
href={`mailto:${brandConfig.supportEmail}`}
|
||||
className='underline-offset-4 transition hover:underline'
|
||||
>
|
||||
Contact support
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</AuthBackground>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user