The crowdsale UI now has comprehensive status indicators that clearly show the current state of the crowdsale contract and whether timers are set.
Dynamic banner that shows the current crowdsale state with appropriate styling and animations.
🔴 Not Deployed
- When: Contract not deployed or no address in
.env.local - Color: Orange/Red gradient
- Icon: Alert Circle
- Message: "The crowdsale contract is not deployed on this network"
🔵 Loading
- When: Fetching data from blockchain
- Color: Blue/Purple gradient
- Icon: Clock (rotating)
- Message: "Fetching data from the blockchain..."
🟡 Not Started
- When: Contract deployed but opening time hasn't been reached
- Color: Yellow/Orange gradient
- Icon: Clock
- Message: "The crowdsale will begin soon. Check the countdown below."
🟢 Active (LIVE badge)
- When: Current time is between opening and deadline
- Color: Green/Emerald gradient
- Icon: Check Circle (pulsing)
- Message: "The crowdsale is live! Purchase tokens now."
- Badge: Animated "LIVE" indicator
⚫ Ended
- When: Current time is past deadline
- Color: Gray gradient
- Icon: X Circle
- Message: "The crowdsale has concluded. Thank you for participating!"
┌────────────────────────┐
│ Opening In / Closing In │
├────────────────────────┤
│ [Days] [Hrs] [Min] [Sec] │
└────────────────────────┘
┌────────────────────────┐
│ ⏰ (icon) │
│ No Timer Set │
│ │
│ Deploy the crowdsale │
│ contract to see the │
│ countdown timer │
└────────────────────────┘
- Values: Show "N/A" instead of "0"
- Icons: Grayed out
- Indicator: Alert triangle in top-right corner
- Animation: No spinning dot
- Values: Show "..."
- Icons: Normal color
- Animation: No spinning dot
- Values: Show real data
- Icons: Full gradient color
- Animation: Spinning blue/purple dot indicator
┌─────────────────────────────────────┐
│ STATUS BANNER (Prominent) │
│ ┌─────────────────────────────┐ │
│ │ 🔴 Contract Not Deployed │ │
│ │ Deploy contract to continue │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ HERO SECTION │
│ Token Crowdsale (3D Title) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ COUNTDOWN/TIMER │
│ ┌─────────────────────────────┐ │
│ │ ⏰ No Timer Set │ │
│ │ Deploy contract to see... │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ STATS SECTION │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │N/A│ │N/A│ │N/A│ │N/A│ │
│ │⚠️ │ │⚠️ │ │⚠️ │ │⚠️ │ │
│ └───┘ └───┘ └───┘ └───┘ │
└─────────────────────────────────────┘
| Contract Status | Timer Display | Stats Display | Banner Color | Action Needed |
|---|---|---|---|---|
| Not Deployed | "No Timer Set" | "N/A" + |
🔴 Orange | Deploy contract |
| Loading | "No Timer Set" | "..." | 🔵 Blue | Wait |
| Not Started | Countdown | Real data | 🟡 Yellow | Wait for opening |
| Active | Countdown | Real data + • | 🟢 Green | Purchase tokens |
| Ended | Final time | Real data | ⚫ Gray | Sale complete |
bg: from-orange-500/10 to-red-500/10
border: border-orange-500/30
icon: text-orange-400
text: text-orange-300bg: from-blue-500/10 to-purple-500/10
border: border-blue-500/30
icon: text-blue-400 (rotating)
text: text-blue-300bg: from-yellow-500/10 to-orange-500/10
border: border-yellow-500/30
icon: text-yellow-400
text: text-yellow-300bg: from-green-500/10 to-emerald-500/10
border: border-green-500/30
icon: text-green-400 (pulsing)
text: text-green-300
badge: "LIVE" (blinking)bg: from-gray-500/10 to-gray-600/10
border: border-gray-500/30
icon: text-gray-400
text: text-gray-300const getCrowdsaleStatus = () => {
if (!crowdsaleAddress) return "not-deployed";
if (isLoadingCrowdsale) return "loading";
if (openingTime && deadline) {
const now = Math.floor(Date.now() / 1000);
if (now < Number(openingTime)) return "not-started";
if (now > Number(deadline)) return "ended";
if (isOpen) return "active";
}
return "not-started";
};value: crowdsaleStatus === "not-deployed"
? "N/A"
: isLoadingCrowdsale
? "..."
: actualValue{hasTimestamps ? (
<Countdown targetDate={...} />
) : (
<NoTimerPlaceholder />
)}- Desktop: Full banner with icon, title, and description
- Mobile: Stacked layout, icon above text
- Tablet: Horizontal layout maintained
- Entry: Slide down from top (y: -20 → 0)
- Loading state: Rotating clock icon
- Active state: Pulsing check icon + blinking LIVE badge
- Not Deployed: No animation
- Active: Rotating dot indicator (20s)
- Hover: Scale up + 3D rotate
- With timer: Normal countdown animation
- Without timer: Static clock icon, no animation
✓ Status Banner: "Contract Not Deployed" (orange)
✓ Countdown: "No Timer Set" with explanation
✓ Stats: All showing "N/A" with warning icons
✓ Status Banner: "Crowdsale Not Started" (yellow)
✓ Countdown: Shows time until opening
✓ Stats: Shows real data (0 sold, max tokens, price)
✓ Status Banner: "Crowdsale Active" with LIVE badge (green)
✓ Countdown: Shows time until closing
✓ Stats: Shows real data with spinning dots
✓ Status Banner: "Crowdsale Ended" (gray)
✓ Countdown: Shows final countdown (all zeros)
✓ Stats: Shows final numbers
-
src/components/ui/status-banner.tsx(NEW)- Animated status banner component
- 5 different states with colors and icons
-
src/app/page.tsx- Added status detection logic
- Conditional countdown rendering
- Enhanced stats cards with N/A states
- Integrated StatusBanner component
The status indicators work automatically based on:
- Contract deployment (from
.env.local) - Blockchain data (from wagmi hooks)
- Current time (compared to opening/deadline)
No manual configuration needed!
✅ Clear Communication: Users instantly understand the current state ✅ Reduced Confusion: No more "0" values that look like errors ✅ Professional UX: Proper loading and empty states ✅ Visual Hierarchy: Important status at the top ✅ Accessibility: Clear text descriptions, not just icons ✅ Development-Friendly: Easy to test without deployed contracts
╔══════════════════════════════════════════╗
║ 🟠 Contract Not Deployed ║
║ Deploy contract on this network ║
╚══════════════════════════════════════════╝
⏰
No Timer Set
Deploy the crowdsale contract
to see the countdown
┌───┐ ┌───┐ ┌───┐ ┌───┐
│N/A│ │N/A│ │N/A│ │N/A│
│ ⚠ │ │ ⚠ │ │ ⚠ │ │ ⚠ │
└───┘ └───┘ └───┘ └───┘
╔══════════════════════════════════════════╗
║ 🟢 Crowdsale Active [LIVE] ║
║ The crowdsale is live! Purchase now. ║
╚══════════════════════════════════════════╝
Closing In
┌──┐ ┌──┐ ┌──┐ ┌──┐
│05│ │12│ │34│ │56│
│D │ │H │ │M │ │S │
└──┘ └──┘ └──┘ └──┘
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│25000│ │75000│ │0.001│ │ 50% │
│ • │ │ • │ │ • │ │ • │
└─────┘ └─────┘ └─────┘ └─────┘
- Sound notifications on status change
- Browser notifications when sale starts
- Countdown to opening (days/hours)
- Progress bar in status banner
- Social sharing of sale status
- Historical status timeline