Event.tsx
An animated announcement banner component in Plainform that displays promotional events with shiny text effects and border beams
The Event component displays promotional announcements or events with eye-catching animations. It fetches event data from the database and renders an animated banner with border beam effects.
Usage
Basic Implementation
import { Event } from '@/components/Event';
export default function HomePage() {
return (
<main>
<Event />
</main>
);
}In Hero Section
import { Event } from '@/components/Event';
export function Hero() {
return (
<section className="flex flex-col items-center gap-4">
<Event />
<h1>Welcome to Our Product</h1>
<p>Your tagline here</p>
</section>
);
}Features
- Database-Driven: Fetches event data from Prisma database
- Mock Fallback: Displays mock event from locale when no database event exists
- Dynamic Icons: Supports custom icons via SvgFinder or defaults to ✨
- Type-Based Links: Opens product events in new tab, others in same tab
- Animated Text: Shiny text effect with gradient animation
- Border Beams: Dual animated border beams with different colors
- Conditional Rendering: Only displays when event exists
- Responsive: Adapts to mobile and desktop layouts
Implementation Details
Data Fetching
The component uses the getEvent function to fetch data:
export async function getEvent() {
// Fetches latest event from database
// Returns { event: { text, slug, type, icon, timestamp } }
}Returns:
event.text- Event announcement textevent.slug- URL slug for event linkevent.type- Event type: 'post', 'coupon', or 'product'event.icon- Optional icon nameevent.timestamp- Creation timestamp
Mock Event Fallback
If no database event exists, displays mock event from locale:
const data = await getEvent();
const mockEvent = locale?.homePage?.mockEvent;
// Use real event if available, otherwise use mock event
const event = data?.event || mockEvent;Mock event structure in locales/en.json:
{
"homePage": {
"mockEvent": {
"text": "Your event announcement goes here",
"slug": "/#buy",
"type": "coupon",
"icon": null
}
}
}Conditional Rendering
The component returns null if no event exists:
if (!event) {
return null;
}Link Target Behavior
Different event types open in different targets:
const target: Record<string, '_blank' | ''> = {
product: '_blank', // Opens in new tab
post: '', // Opens in same tab
coupon: '', // Opens in same tab
};
<Link
href={event?.slug}
target={target[event?.type] || ''}
>Icon Rendering
Displays custom icon or default sparkle:
{event?.icon ? (
<SvgFinder icon={event?.icon} size={14} />
) : (
<span>✨</span>
)}Animation Effects
The component uses two animated effects:
- AnimatedShinyText: Gradient text animation
- BorderBeam: Dual animated border beams
<Link href={event?.slug} target={target[event?.type] || ''}>
<AnimatedShinyText className="flex items-center gap-4 justify-center">
<div className="flex gap-2 items-center">
{event?.icon ? (
<SvgFinder icon={event?.icon} size={14} />
) : (
<span>✨</span>
)}
<span className="line-clamp-1">{event?.text}</span>
</div>
<MoveRight size={14} />
</AnimatedShinyText>
{/* First border beam - indigo */}
<BorderBeam
duration={6}
size={1000}
initialOffset={1400}
borderWidth={0.5}
className="from-transparent via-indigo-500 to-transparent"
/>
{/* Second border beam - pink */}
<BorderBeam
duration={6}
delay={3}
size={1000}
initialOffset={1400}
borderWidth={0.5}
className="from-transparent via-pink-400 to-transparent"
/>
</Link>Customization
Changing Border Colors
Modify the gradient colors in BorderBeam:
<BorderBeam
duration={6}
size={1000}
initialOffset={1400}
borderWidth={0.5}
className="from-transparent via-blue-500 to-transparent"
/>
<BorderBeam
duration={6}
delay={3}
size={1000}
initialOffset={1400}
borderWidth={0.5}
className="from-transparent via-green-400 to-transparent"
/>Adjusting Animation Speed
Change the duration prop:
<BorderBeam
duration={3}
size={1000}
initialOffset={1400}
borderWidth={0.5}
className="from-transparent via-indigo-500 to-transparent"
/>Border Width
Adjust the border thickness:
<BorderBeam
duration={6}
size={1000}
initialOffset={1400}
borderWidth={1.5}
className="from-transparent via-indigo-500 to-transparent"
/>Custom Link Targets
Modify the target behavior:
const target: Record<string, '_blank' | ''> = {
product: '_blank',
post: '_blank', // Open posts in new tab
coupon: '',
};Database Schema
The event data comes from the Prisma database:
model Event {
id String @id @default(cuid())
type String // 'post', 'coupon', or 'product'
slug String // URL to link to
text String // Display text
icon String? // Optional icon name
timestamp BigInt // Creation timestamp
@@index([type])
}Creating Events
To add a new event, use the Events API:
POST http://localhost:3000/api/events
Content-Type: application/json
Authorization: Bearer your_event_api_secret
{
"text": "🎉 New feature launched! Check it out",
"type": "post",
"slug": "/blog/new-feature-launch",
"icon": "Rocket"
}The component will automatically display the latest event.
For more details, see Events Documentation.
Related
- Events Overview - Events system documentation
- AnimatedShinyText.tsx - Text animation component
- BorderBeam.tsx - Border animation component
How is this guide ?
Last updated on