Vector Motion
Education

Announcement Card - Communications Dashboard

Display school announcements and notices efficiently. Manage communications with students, parents, and staff.

Announcement Card

The Announcement Card displays important school board announcements and notices with timestamps and visual indicators.

Preview

Installation

npx shadcn@latest add https://vectormotion.vercel.app/registry/announcement-card.json
Announcement Card
'use client'import React from 'react';import { Megaphone, MessageCircle } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";function cn(...inputs: ClassValue[]) {  return twMerge(clsx(inputs));}interface AnnouncementCardProps {  className?: string;  title?: string;  subtitle?: string;  announcementTitle?: string;  announcementContent?: string;  timeAgo?: string;  commentCount?: string;  hasUnread?: boolean;}const DEFAULT_TITLE = "Notices";const DEFAULT_SUBTITLE = "School Board";const DEFAULT_ANNOUNCEMENT_TITLE = "Staff Development Day";const DEFAULT_ANNOUNCEMENT_CONTENT = "School will be closed this Friday for staff training. Regular classes resume Monday.";const DEFAULT_TIME_AGO = "2 hours ago";const DEFAULT_COMMENT_COUNT = "5 comments";export const AnnouncementCard: React.FC<AnnouncementCardProps> = ({  className = "",  title = DEFAULT_TITLE,  subtitle = DEFAULT_SUBTITLE,  announcementTitle = DEFAULT_ANNOUNCEMENT_TITLE,  announcementContent = DEFAULT_ANNOUNCEMENT_CONTENT,  timeAgo = DEFAULT_TIME_AGO,  commentCount = DEFAULT_COMMENT_COUNT,  hasUnread = true,}) => {  return (    <motion.div      initial={{ opacity: 0, y: 20 }}      animate={{ opacity: 1, y: 0 }}      transition={{ duration: 0.5, delay: 0.1 }}      className={cn(        "relative overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition-all hover:border-orange-300 dark:hover:border-orange-700 hover:shadow-md flex flex-col h-full",        className      )}    >      <div className="absolute top-0 right-0 p-4 opacity-5 pointer-events-none">        <Megaphone className="w-24 h-24 text-orange-500 transform rotate-12" />      </div>      <div className="p-5 flex flex-col h-full relative z-10">        <div className="mb-4 flex items-start justify-between">          <div>            <h3 className="font-bold text-lg text-foreground">              {title}            </h3>            <p className="text-sm text-muted-foreground font-medium">              {subtitle}            </p>          </div>          <div className="relative">            <div className="rounded-xl bg-orange-500/10 p-2.5 text-orange-500 dark:text-orange-400 flex items-center justify-center ring-1 ring-orange-100 dark:ring-orange-800">              <Megaphone className="h-5 w-5" />            </div>            {hasUnread && (              <motion.span                initial={{ scale: 0 }}                animate={{ scale: 1 }}                transition={{ delay: 1, type: "spring" }}                className="absolute -top-1 -right-1 h-3 w-3 bg-red-500 rounded-full border-2 border-white dark:border-zinc-900"              />            )}          </div>        </div>        <div className="flex-1 flex flex-col justify-center space-y-3">          <motion.div            initial={{ x: -20, opacity: 0 }}            animate={{ x: 0, opacity: 1 }}            transition={{ delay: 0.2 }}            className="p-3 bg-orange-50 dark:bg-orange-900/10 rounded-lg border border-orange-100 dark:border-orange-900/20 relative"          >            <div className="absolute -left-1 top-4 w-2 h-2 bg-orange-400 rounded-full" />            <h4 className="text-sm font-semibold text-zinc-800 dark:text-zinc-200 mb-1">{announcementTitle}</h4>            <p className="text-xs text-zinc-600 dark:text-muted-foreground leading-relaxed">              {announcementContent}            </p>            <div className="flex items-center gap-2 mt-2">              <span className="text-[10px] text-zinc-400 font-medium">{timeAgo}</span>              <div className="flex items-center gap-1 text-[10px] text-orange-500 font-medium">                <MessageCircle className="w-3 h-3" />                <span>{commentCount}</span>              </div>            </div>          </motion.div>        </div>      </div>    </motion.div>  );};

Usage

This component provides a visually appealing way to display school announcements, keeping students, parents, and staff informed of important updates.

Prop

Type