Franknoirot/loading states (#246)
* Add Loading state with long load time messaging * Make /signin page respect user theme
This commit is contained in:
@ -5,6 +5,7 @@ import { User, useStore } from './useStore'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useEffect } from 'react'
|
||||
import { isTauri } from './lib/isTauri'
|
||||
import Loading from './components/Loading'
|
||||
|
||||
// Wrapper around protected routes, used in src/Router.tsx
|
||||
export const Auth = ({ children }: React.PropsWithChildren) => {
|
||||
@ -30,5 +31,5 @@ export const Auth = ({ children }: React.PropsWithChildren) => {
|
||||
}
|
||||
}, [user, token, navigate, isLoading])
|
||||
|
||||
return isLoading ? <>Loading...</> : <>{children}</>
|
||||
return isLoading ? <Loading /> : <>{children}</>
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ export const ActionButton = ({
|
||||
children,
|
||||
...props
|
||||
}: ActionButtonProps) => {
|
||||
const classNames = `group mono text-base flex items-center gap-2 rounded-sm border border-chalkboard-40 dark:border-chalkboard-60 hover:border-liquid-40 dark:hover:bg-chalkboard-90 p-[3px] ${
|
||||
const classNames = `group mono text-base flex items-center gap-2 rounded-sm border border-chalkboard-40 dark:border-chalkboard-60 hover:border-liquid-40 dark:hover:bg-chalkboard-90 p-[3px] text-chalkboard-110 dark:text-chalkboard-10 hover:text-chalkboard-110 hover:dark:text-chalkboard-10 ${
|
||||
icon ? 'pr-2' : 'px-2'
|
||||
} ${className}`
|
||||
|
||||
|
||||
41
src/components/Loading.tsx
Normal file
41
src/components/Loading.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const Loading = () => {
|
||||
const [hasLongLoadTime, setHasLongLoadTime] = useState(false)
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setHasLongLoadTime(true)
|
||||
}, 4000)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [setHasLongLoadTime])
|
||||
return (
|
||||
<div className="body-bg flex flex-col items-center justify-center h-screen">
|
||||
<svg viewBox="0 0 10 10" className="w-8 h-8">
|
||||
<circle cx="5" cy="5" r="4" stroke="var(--liquid-20)" fill="none" />
|
||||
<circle
|
||||
cx="5"
|
||||
cy="5"
|
||||
r="4"
|
||||
stroke="var(--liquid-10)"
|
||||
fill="none"
|
||||
strokeDasharray="4, 4"
|
||||
className="animate-spin origin-center"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mt-4 text-liquid-80 dark:text-liquid-20">
|
||||
Loading KittyCAD Modeling App...
|
||||
</p>
|
||||
<p
|
||||
className={
|
||||
'mt-4 text-liquid-90 dark:text-liquid-10 transition-opacity duration-500' +
|
||||
(hasLongLoadTime ? ' opacity-100' : ' opacity-0')
|
||||
}
|
||||
>
|
||||
Loading is taking longer than expected.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loading
|
||||
@ -55,6 +55,14 @@ button:disabled {
|
||||
@apply bg-chalkboard-90 text-chalkboard-40 border-chalkboard-70;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply text-liquid-80 hover:text-liquid-70;
|
||||
}
|
||||
|
||||
.dark a {
|
||||
@apply text-liquid-20 hover:text-liquid-10;
|
||||
}
|
||||
|
||||
.mono {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import { ActionButton } from '../components/ActionButton'
|
||||
import { isTauri } from '../lib/isTauri'
|
||||
import { useStore } from '../useStore'
|
||||
import { Themes, useStore } from '../useStore'
|
||||
import { invoke } from '@tauri-apps/api/tauri'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { VITE_KC_SITE_BASE_URL, VITE_KC_API_BASE_URL } from '../env'
|
||||
import { getSystemTheme } from '../lib/getSystemTheme'
|
||||
|
||||
const SignIn = () => {
|
||||
const navigate = useNavigate()
|
||||
const { setToken } = useStore((s) => ({
|
||||
const { setToken, theme } = useStore((s) => ({
|
||||
setToken: s.setToken,
|
||||
theme: s.theme,
|
||||
}))
|
||||
const appliedTheme = theme === Themes.System ? getSystemTheme() : theme
|
||||
const signInTauri = async () => {
|
||||
// We want to invoke our command to login via device auth.
|
||||
try {
|
||||
@ -25,11 +28,13 @@ const SignIn = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="h-full min-h-screen bg-chalkboard-20 dark:text-chalkboard-100 m-0 p-0 pt-24">
|
||||
<main className="body-bg h-full min-h-screen m-0 p-0 pt-24">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div>
|
||||
<img
|
||||
src="/kittycad-logomark.svg"
|
||||
src={`/kittycad-logomark${
|
||||
appliedTheme === Themes.Dark ? '-light' : ''
|
||||
}.svg`}
|
||||
alt="KittyCAD"
|
||||
className="w-48 inline-block"
|
||||
/>
|
||||
@ -37,7 +42,7 @@ const SignIn = () => {
|
||||
Modeling App
|
||||
</span>
|
||||
</div>
|
||||
<h1 className="font-bold text-2xl mt-12 mb-6 text-chalkboard-110">
|
||||
<h1 className="font-bold text-2xl mt-12 mb-6">
|
||||
Sign in to get started with the KittyCAD Modeling App
|
||||
</h1>
|
||||
<p className="py-4">
|
||||
@ -51,14 +56,7 @@ const SignIn = () => {
|
||||
<p className="py-4">
|
||||
KCMA is currently in development. If you would like to be notified
|
||||
when KCMA is ready for production, please sign up for our mailing list
|
||||
at{' '}
|
||||
<a
|
||||
href="https://kittycad.io"
|
||||
className="font-bold text-liquid-80 hover:text-liquid-70"
|
||||
>
|
||||
kittycad.io
|
||||
</a>
|
||||
.
|
||||
at <a href="https://kittycad.io">kittycad.io</a>.
|
||||
</p>
|
||||
{isTauri() ? (
|
||||
<ActionButton
|
||||
@ -76,7 +74,7 @@ const SignIn = () => {
|
||||
window.location.href.replace('signin', '')
|
||||
)}`}
|
||||
icon={{ icon: faSignInAlt }}
|
||||
className="w-fit mt-4 dark:hover:bg-chalkboard-30"
|
||||
className="w-fit mt-4"
|
||||
>
|
||||
Sign in
|
||||
</ActionButton>
|
||||
|
||||
Reference in New Issue
Block a user