Spaces:
Sleeping
Sleeping
| 'use client'; | |
| import { Room } from '@/types'; | |
| import { motion } from 'framer-motion'; | |
| import { Users, Play, Lock } from 'lucide-react'; | |
| import { useRouter } from 'next/navigation'; | |
| interface RoomCardProps { | |
| room: Room; | |
| index: number; | |
| } | |
| export default function RoomCard({ room, index }: RoomCardProps) { | |
| const router = useRouter(); | |
| return ( | |
| <motion.div | |
| initial={{ opacity: 0, y: 20 }} | |
| animate={{ opacity: 1, y: 0 }} | |
| transition={{ delay: index * 0.1 }} | |
| whileHover={{ scale: 1.05 }} | |
| whileTap={{ scale: 0.95 }} | |
| onClick={() => router.push(`/room/${room.id}`)} | |
| className="cursor-pointer group relative overflow-hidden rounded-3xl bg-party-card border border-white/10 p-6 backdrop-blur-md transition-all duration-300 hover:bg-party-cardHover hover:border-pop-pink/50 hover:shadow-[0_0_30px_rgba(255,0,127,0.3)]" | |
| > | |
| <div className="absolute top-0 right-0 p-4 opacity-50"> | |
| <div className={`w-24 h-24 rounded-full blur-2xl ${room.status === 'PLAYING' ? 'bg-pop-orange' : 'bg-pop-cyan'} opacity-20 group-hover:opacity-40 transition-opacity`} /> | |
| </div> | |
| <div className="relative z-10 flex flex-col h-full justify-between"> | |
| <div> | |
| <div className="flex justify-between items-start mb-4"> | |
| <span className="inline-flex items-center gap-1 rounded-full bg-white/10 px-3 py-1 text-xs font-bold text-pop-cyan backdrop-blur-sm border border-white/5"> | |
| {room.gameType} | |
| </span> | |
| {room.status === 'PLAYING' && ( | |
| <span className="inline-flex items-center gap-1 rounded-full bg-pop-orange/20 px-3 py-1 text-xs font-bold text-pop-orange border border-pop-orange/30"> | |
| Bermain | |
| </span> | |
| )} | |
| </div> | |
| <h3 className="font-display text-2xl font-bold text-white mb-1 truncate group-hover:text-pop-pink transition-colors"> | |
| {room.name} | |
| </h3> | |
| <p className="text-white/60 text-sm">Host oleh {room.hostId.slice(0, 5)}...</p> | |
| </div> | |
| <div className="mt-6"> | |
| <div className="flex items-center justify-between text-sm font-bold text-white/80 mb-2"> | |
| <div className="flex items-center gap-2"> | |
| <Users size={16} className="text-pop-yellow" /> | |
| <span>{room.players.length} / {room.maxPlayers}</span> | |
| </div> | |
| {!room.isPublic && <Lock size={16} className="text-white/40" />} | |
| </div> | |
| {/* Progress Bar */} | |
| <div className="h-2 w-full bg-black/30 rounded-full overflow-hidden"> | |
| <motion.div | |
| initial={{ width: 0 }} | |
| animate={{ width: `${(room.players.length / room.maxPlayers) * 100}%` }} | |
| className="h-full bg-gradient-to-r from-pop-purple to-pop-pink" | |
| /> | |
| </div> | |
| <div className="mt-4 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-x-0"> | |
| <button className="w-full py-2 bg-white text-pop-purple font-display font-bold rounded-xl shadow-lg hover:bg-pop-yellow hover:text-black transition-colors flex items-center justify-center gap-2"> | |
| GABUNG <Play size={16} fill="currentColor" /> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </motion.div> | |
| ); | |
| } | |