diff --git a/web/components/SettledUpState.tsx b/web/components/SettledUpState.tsx new file mode 100644 index 00000000..3fbae54c --- /dev/null +++ b/web/components/SettledUpState.tsx @@ -0,0 +1,52 @@ +import { motion } from 'framer-motion'; +import { Check } from 'lucide-react'; +import React from 'react'; +import { THEMES } from '../constants'; +import { useTheme } from '../contexts/ThemeContext'; +import { Confetti } from './ui/Confetti'; + +export const SettledUpState = () => { + const { style } = useTheme(); + + return ( +
+ + + + + + + + + +

+ All Settled Up! +

+

No outstanding balances in this group.

+
+
+ ); +}; diff --git a/web/components/ui/Confetti.tsx b/web/components/ui/Confetti.tsx new file mode 100644 index 00000000..53cd4c79 --- /dev/null +++ b/web/components/ui/Confetti.tsx @@ -0,0 +1,65 @@ +import { motion } from 'framer-motion'; +import React, { useEffect, useState } from 'react'; +import { COLORS } from '../../constants'; + +interface ConfettiProps { + count?: number; +} + +interface Particle { + id: number; + x: number; + y: number; + color: string; + size: number; + rotation: number; + duration: number; + delay: number; +} + +export const Confetti = ({ count = 50 }: ConfettiProps) => { + const [particles, setParticles] = useState([]); + + useEffect(() => { + const newParticles: Particle[] = Array.from({ length: count }).map((_, i) => ({ + id: i, + x: Math.random() * 100, // percent + y: -10, // start above + color: COLORS[Math.floor(Math.random() * COLORS.length)], + size: Math.random() * 8 + 4, + rotation: Math.random() * 360, + duration: Math.random() * 2 + 2, + delay: Math.random() * 0.5, + })); + setParticles(newParticles); + }, [count]); + + return ( + + ); +}; diff --git a/web/pages/GroupDetails.tsx b/web/pages/GroupDetails.tsx index b2b76c25..62ffe176 100644 --- a/web/pages/GroupDetails.tsx +++ b/web/pages/GroupDetails.tsx @@ -3,6 +3,7 @@ import { ArrowRight, Banknote, Check, Copy, DollarSign, Hash, Layers, LogOut, Pi import React, { useEffect, useMemo, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { AnalyticsContent } from '../components/AnalyticsContent'; +import { SettledUpState } from '../components/SettledUpState'; import { Button } from '../components/ui/Button'; import { Input } from '../components/ui/Input'; import { Modal } from '../components/ui/Modal'; @@ -847,13 +848,7 @@ export const GroupDetails = () => { ))} {!loading && settlements.length === 0 && ( -
-
- -
-

All Settled Up!

-

No outstanding balances in this group.

-
+ )} )}