Add floating generation status card
Browse files
frontend/src/App.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { AnimatePresence } from 'framer-motion'
|
|
| 3 |
import { Navbar } from '@/components/layout/Navbar'
|
| 4 |
import { Footer } from '@/components/layout/Footer'
|
| 5 |
import { BackgroundEffects } from '@/components/features/BackgroundEffects'
|
|
|
|
| 6 |
import { Hero } from '@/components/features/Hero'
|
| 7 |
import { InputPanel } from '@/components/features/InputPanel'
|
| 8 |
import { ResultsSection } from '@/components/features/ResultsSection'
|
|
@@ -28,6 +29,7 @@ export default function App() {
|
|
| 28 |
<div className="relative min-h-screen overflow-x-hidden">
|
| 29 |
<BackgroundEffects />
|
| 30 |
<Navbar />
|
|
|
|
| 31 |
|
| 32 |
<main className="relative z-10 pb-16 pt-24">
|
| 33 |
<section className="mx-auto max-w-7xl px-4 sm:px-6">
|
|
|
|
| 3 |
import { Navbar } from '@/components/layout/Navbar'
|
| 4 |
import { Footer } from '@/components/layout/Footer'
|
| 5 |
import { BackgroundEffects } from '@/components/features/BackgroundEffects'
|
| 6 |
+
import { GenerationStatusCard } from '@/components/features/GenerationStatusCard'
|
| 7 |
import { Hero } from '@/components/features/Hero'
|
| 8 |
import { InputPanel } from '@/components/features/InputPanel'
|
| 9 |
import { ResultsSection } from '@/components/features/ResultsSection'
|
|
|
|
| 29 |
<div className="relative min-h-screen overflow-x-hidden">
|
| 30 |
<BackgroundEffects />
|
| 31 |
<Navbar />
|
| 32 |
+
<GenerationStatusCard visible={state === 'success' && !!result} />
|
| 33 |
|
| 34 |
<main className="relative z-10 pb-16 pt-24">
|
| 35 |
<section className="mx-auto max-w-7xl px-4 sm:px-6">
|
frontend/src/components/features/GenerationStatusCard.tsx
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { motion, AnimatePresence } from 'framer-motion'
|
| 2 |
+
|
| 3 |
+
interface GenerationStatusCardProps {
|
| 4 |
+
visible: boolean
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
const cardAnimation = {
|
| 8 |
+
hidden: {
|
| 9 |
+
x: -220,
|
| 10 |
+
rotate: -6,
|
| 11 |
+
opacity: 0,
|
| 12 |
+
},
|
| 13 |
+
visible: {
|
| 14 |
+
x: [ -220, 20, -10, 6, 0, -3, 0 ],
|
| 15 |
+
rotate: [ -6, -2, -4, -2.5, -3.5, -3, -3 ],
|
| 16 |
+
opacity: 1,
|
| 17 |
+
transition: {
|
| 18 |
+
duration: 0.72,
|
| 19 |
+
times: [0, 0.5, 0.68, 0.8, 0.9, 0.96, 1],
|
| 20 |
+
ease: 'easeOut',
|
| 21 |
+
},
|
| 22 |
+
},
|
| 23 |
+
exit: {
|
| 24 |
+
x: -220,
|
| 25 |
+
rotate: -8,
|
| 26 |
+
opacity: 0,
|
| 27 |
+
transition: {
|
| 28 |
+
duration: 0.22,
|
| 29 |
+
ease: 'easeIn',
|
| 30 |
+
},
|
| 31 |
+
},
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
export function GenerationStatusCard({ visible }: GenerationStatusCardProps) {
|
| 35 |
+
return (
|
| 36 |
+
<AnimatePresence>
|
| 37 |
+
{visible && (
|
| 38 |
+
<motion.aside
|
| 39 |
+
variants={cardAnimation}
|
| 40 |
+
initial="hidden"
|
| 41 |
+
animate="visible"
|
| 42 |
+
exit="exit"
|
| 43 |
+
className="pointer-events-none fixed bottom-6 left-4 z-40 w-[min(18rem,calc(100vw-2rem))] sm:bottom-8 sm:left-6"
|
| 44 |
+
>
|
| 45 |
+
<div className="border-[4px] border-[#111111] bg-[#f6dd74] px-4 py-4 shadow-[10px_10px_0_#111111]">
|
| 46 |
+
<div className="mb-3 inline-flex border-[3px] border-[#111111] bg-[#fff7dc] px-2 py-1 font-['IBM_Plex_Mono'] text-[10px] font-semibold uppercase tracking-[0.18em] text-[#111111]">
|
| 47 |
+
Status note
|
| 48 |
+
</div>
|
| 49 |
+
|
| 50 |
+
<p className="font-['IBM_Plex_Mono'] text-[1.05rem] font-semibold uppercase leading-tight text-[#111111]">
|
| 51 |
+
Let's break some trust.
|
| 52 |
+
</p>
|
| 53 |
+
|
| 54 |
+
<p className="mt-3 font-['IBM_Plex_Mono'] text-[0.76rem] font-semibold uppercase tracking-[0.16em] text-[#2b2b2b]">
|
| 55 |
+
Scroll down ↓
|
| 56 |
+
</p>
|
| 57 |
+
</div>
|
| 58 |
+
</motion.aside>
|
| 59 |
+
)}
|
| 60 |
+
</AnimatePresence>
|
| 61 |
+
)
|
| 62 |
+
}
|